mirror of
https://github.com/larsbrinkhoff/awesome-cpus
synced 2025-04-16 10:04:37 +03:00
10429 lines
451 KiB
Plaintext
10429 lines
451 KiB
Plaintext
INTEL 80386 PROGRAMMER'S REFERENCE MANUAL 1986
|
||
|
||
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, Intel Certified, Intelevision,
|
||
inteligent Identifier, inteligent Programming, Intellec, Intellink,
|
||
iOSP, iPDS, iPSC, iRMK, iRMX, iSBC, iSBX, iSDM, iSXM, KEPROM, Library
|
||
Manager, MAPNET, 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, SugarCube, SupportNET, UPI, and VLSiCEL, and the
|
||
combination of ICE, iCS, iRMX, iSBC, iSBX, iSXM, 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.
|
||
|
||
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-5/26/87
|
||
|
||
|
||
Customer Support
|
||
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
Customer Support is Intel's complete support service that provides Intel
|
||
customers with hardware support, software support, customer training, and
|
||
consulting services. For more information contact your local sales offices.
|
||
|
||
After a customer purchases any system hardware or software product,
|
||
service and support become major factors in determining whether that
|
||
product will continue to meet a customer's expectations. Such support
|
||
requires an international support organization and a breadth of programs
|
||
to meet a variety of customer needs. As you might expect, Intel's customer
|
||
support is quite extensive. It includes factory repair services and
|
||
worldwide field service offices providing hardware repair services,
|
||
software support services, customer training classes, and consulting
|
||
services.
|
||
|
||
Hardware Support Services
|
||
|
||
Intel is committed to providing an international service support package
|
||
through a wide variety of service offerings available from Intel Hardware
|
||
Support.
|
||
|
||
Software Support Services
|
||
|
||
Intel's software support consists of two levels of contracts. Standard
|
||
support includes TIPS (Technical Information Phone Service), updates and
|
||
subscription service (product-specific troubleshooting guides and COMMENTS
|
||
Magazine). Basic support includes updates and the subscription service.
|
||
Contracts are sold in environments which represent product groupings
|
||
(i.e., iRMX environment).
|
||
|
||
Consulting Services
|
||
|
||
Intel provides field systems engineering services for any phase of your
|
||
development or support effort. You can use our systems engineers in a
|
||
variety of ways ranging from assistance in using a new product, developing
|
||
an application, personalizing training, and customizing or tailoring an
|
||
Intel product to providing technical and management consulting. Systems
|
||
Engineers are well versed in technical areas such as microcommunications,
|
||
real-time applications, embedded microcontrollers, and network services.
|
||
You know your application needs; we know our products. Working together we
|
||
can help you get a successful product to market in the least possible time.
|
||
|
||
Customer Training
|
||
|
||
Intel offers a wide range of instructional programs covering various
|
||
aspects of system design and implementation. In just three to ten days a
|
||
limited number of individuals learn more in a single workshop than in
|
||
weeks of self-study. For optimum convenience, workshops are scheduled
|
||
regularly at Training Centers woridwide or we can take our workshops to
|
||
you for on-site instruction. Covering a wide variety of topics, Intel's
|
||
major course categories include: architecture and assembly language,
|
||
programming and operating systems, bitbus and LAN applications.
|
||
|
||
Training Center Locations
|
||
|
||
To obtain a complete catalog of our workshops, call the nearest Training
|
||
Center in your area.
|
||
|
||
Boston (617) 692-1000
|
||
Chicago (312) 310-5700
|
||
San Francisco (415) 940-7800
|
||
Washington D.C. (301) 474-2878
|
||
Isreal (972) 349-491-099
|
||
Tokyo 03-437-6611
|
||
Osaka (Call Tokyo) 03-437-6611
|
||
Toronto, Canada (416) 675-2105
|
||
London (0793) 696-000
|
||
Munich (089) 5389-1
|
||
Paris (01) 687-22-21
|
||
Stockholm (468) 734-01-00
|
||
Milan 39-2-82-44-071
|
||
Benelux (Rotterdam) (10) 21-23-77
|
||
Copenhagen (1) 198-033
|
||
Hong Kong 5-215311-7
|
||
|
||
|
||
Table of Contents
|
||
|
||
Chapter 1 Introduction to the 80386
|
||
|
||
1.1 Organization of This Manual
|
||
1.1.1 Part I ÄÄ Applications Programming
|
||
1.1.2 Part II ÄÄ Systems Programming
|
||
1.1.3 Part III ÄÄ Compatibility
|
||
1.1.4 Part IV ÄÄ Instruction Set
|
||
1.1.5 Appendices
|
||
|
||
1.2 Related Literature
|
||
1.3 Notational Conventions
|
||
1.3.1 Data-Structure Formats
|
||
1.3.2 Undefined Bits and Software Compatibility
|
||
1.3.3 Instruction Operands
|
||
1.3.4 Hexadecimal Numbers
|
||
1.3.5 Sub- and Super-Scripts
|
||
|
||
PART I APPLICATIONS PROGRAMMING
|
||
|
||
Chapter 2 Basic Programming Model
|
||
|
||
2.1 Memory Organization and Segmentation
|
||
2.1.1 The"Flat" Model
|
||
2.1.2 The Segmented Model
|
||
|
||
2.2 Data Types
|
||
2.3 Registers
|
||
2.3.1 General Registers
|
||
2.3.2 Segment Registers
|
||
2.3.3 Stack Implementation
|
||
2.3.4 Flags Register
|
||
2.3.4.1 Status Flags
|
||
2.3.4.2 Control Flag
|
||
2.3.4.3 Instruction Pointer
|
||
|
||
2.4 Instruction Format
|
||
2.5 Operand Selection
|
||
2.5.1 Immediate Operands
|
||
2.5.2 Register Operands
|
||
2.5.3 Memory Operands
|
||
2.5.3.1 Segment Selection
|
||
2.5.3.2 Effective-Address Computation
|
||
|
||
2.6 Interrupts and Exceptions
|
||
|
||
Chapter 3 Applications Instruction Set
|
||
|
||
3.1 Data Movement Instructions
|
||
3.1.1 General-Purpose Data Movement Instructions
|
||
3.1.2 Stack Manipulation Instructions
|
||
3.1.3 Type Conversion Instructions
|
||
|
||
3.2 Binary Arithmetic Instructions
|
||
3.2.1 Addition and Subtraction Instructions
|
||
3.2.2 Comparison and Sign Change Instruction
|
||
3.2.3 Multiplication Instructions
|
||
3.2.4 Division Instructions
|
||
|
||
3.3 Decimal Arithmetic Instructions
|
||
3.3.1 Packed BCD Adjustment Instructions
|
||
3.3.2 Unpacked BCD Adjustment Instructions
|
||
|
||
3.4 Logical Instructions
|
||
3.4.1 Boolean Operation Instructions
|
||
3.4.2 Bit Test and Modify Instructions
|
||
3.4.3 Bit Scan Instructions
|
||
3.4.4 Shift and Rotate Instructions
|
||
3.4.4.1 Shift Instructions
|
||
3.4.4.2 Double-Shift Instructions
|
||
3.4.4.3 Rotate Instructions
|
||
3.4.4.4 Fast"bit-blt" Using Double Shift
|
||
Instructions
|
||
3.4.4.5 Fast Bit-String Insert and Extract
|
||
|
||
3.4.5 Byte-Set-On-Condition Instructions
|
||
3.4.6 Test Instruction
|
||
|
||
3.5 Control Transfer Instructions
|
||
3.5.1 Unconditional Transfer Instructions
|
||
3.5.1.1 Jump Instruction
|
||
3.5.1.2 Call Instruction
|
||
3.5.1.3 Return and Return-From-Interrupt Instruction
|
||
|
||
3.5.2 Conditional Transfer Instructions
|
||
3.5.2.1 Conditional Jump Instructions
|
||
3.5.2.2 Loop Instructions
|
||
3.5.2.3 Executing a Loop or Repeat Zero Times
|
||
|
||
3.5.3 Software-Generated Interrupts
|
||
|
||
3.6 String and Character Translation Instructions
|
||
3.6.1 Repeat Prefixes
|
||
3.6.2 Indexing and Direction Flag Control
|
||
3.6.3 String Instructions
|
||
|
||
3.7 Instructions for Block-Structured Languages
|
||
3.8 Flag Control Instructions
|
||
3.8.1 Carry and Direction Flag Control Instructions
|
||
3.8.2 Flag Transfer Instructions
|
||
|
||
3.9 Coprocessor Interface Instructions
|
||
3.10 Segment Register Instructions
|
||
3.10.1 Segment-Register Transfer Instructions
|
||
3.10.2 Far Control Transfer Instructions
|
||
3.10.3 Data Pointer Instructions
|
||
|
||
3.11 Miscellaneous Instructions
|
||
3.11.1 Address Calculation Instruction
|
||
3.11.2 No-Operation Instruction
|
||
3.11.3 Translate Instruction
|
||
|
||
PART II SYSTEMS PROGRAMMING
|
||
|
||
Chapter 4 Systems Architecture
|
||
|
||
4.1 Systems Registers
|
||
4.1.1 Systems Flags
|
||
4.1.2 Memory-Management Registers
|
||
4.1.3 Control Registers
|
||
4.1.4 Debug Register
|
||
4.1.5 Test Registers
|
||
|
||
4.2 Systems Instructions
|
||
|
||
Chapter 5 Memory Management
|
||
|
||
5.1 Segment Translation
|
||
5.1.1 Descriptors
|
||
5.1.2 Descriptor Tables
|
||
5.1.3 Selectors
|
||
5.1.4 Segment Registers
|
||
|
||
5.2 Page Translation
|
||
5.2.1 Page Frame
|
||
5.2.2 Linear Address
|
||
5.2.3 Page Tables
|
||
5.2.4 Page-Table Entries
|
||
5.2.4.1 Page Frame Address
|
||
5.2.4.2 Present Bit
|
||
5.2.4.3 Accessed and Dirty Bits
|
||
5.2.4.4 Read/Write and User/Supervisor Bits
|
||
|
||
5.2.5 Page Translation Cache
|
||
|
||
5.3 Combining Segment and Page Translation
|
||
5.3.1 "Flat" Architecture
|
||
5.3.2 Segments Spanning Several Pages
|
||
5.3.3 Pages Spanning Several Segments
|
||
5.3.4 Non-Aligned Page and Segment Boundaries
|
||
5.3.5 Aligned Page and Segment Boundaries
|
||
5.3.6 Page-Table per Segment
|
||
|
||
Chapter 6 Protection
|
||
|
||
6.1 Why Protection?
|
||
6.2 Overview of 80386 Protection Mechanisms
|
||
6.3 Segment-Level Protection
|
||
6.3.1 Descriptors Store Protection Parameters
|
||
6.3.1.1 Type Checking
|
||
6.3.1.2 Limit Checking
|
||
6.3.1.3 Privilege Levels
|
||
|
||
6.3.2 Restricting Access to Data
|
||
6.3.2.1 Accessing Data in Code Segments
|
||
|
||
6.3.3 Restricting Control Transfers
|
||
6.3.4 Gate Descriptors Guard Procedure Entry Points
|
||
6.3.4.1 Stack Switching
|
||
6.3.4.2 Returning from a Procedure
|
||
|
||
6.3.5 Some Instructions are Reserved for Operating System
|
||
6.3.5.1 Privileged Instructions
|
||
6.3.5.2 Sensitive Instructions
|
||
|
||
6.3.6 Instructions for Pointer Validation
|
||
6.3.6.1 Descriptor Validation
|
||
6.3.6.2 Pointer Integrity and RPL
|
||
|
||
6.4 Page-Level Protection
|
||
6.4.1 Page-Table Entries Hold Protection Parameters
|
||
6.4.1.1 Restricting Addressable Domain
|
||
6.4.1.2 Type Checking
|
||
|
||
6.4.2 Combining Protection of Both Levels of Page Tables
|
||
6.4.3 Overrides to Page Protection
|
||
|
||
6.5 Combining Page and Segment Protection
|
||
|
||
Chapter 7 Multitasking
|
||
|
||
7.1 Task State Segment
|
||
7.2 TSS Descriptor
|
||
7.3 Task Register
|
||
7.4 Task Gate Descriptor
|
||
7.5 Task Switching
|
||
7.6 Task Linking
|
||
7.6.1 Busy Bit Prevents Loops
|
||
7.6.2 Modifying Task Linkages
|
||
|
||
7.7 Task Address Space
|
||
7.7.1 Task Linear-to-Physical Space Mapping
|
||
7.7.2 Task Logical Address Space
|
||
|
||
Chapter 8 Input/Output
|
||
|
||
8.1 I/O Addressing
|
||
8.1.1 I/O Address Space
|
||
8.1.2 Memory-Mapped I/O
|
||
|
||
8.2 I/O Instructions
|
||
8.2.1 Register I/O Instructions
|
||
8.2.2 Block I/O Instructions
|
||
|
||
8.3 Protection and I/O
|
||
8.3.1 I/O Privilege Level
|
||
8.3.2 I/O Permission Bit Map
|
||
|
||
Chapter 9 Exceptions and Interrupts
|
||
|
||
9.1 Identifying Interrupts
|
||
9.2 Enabling and Disabling Interrupts
|
||
9.2.1 NMI Masks Further NMls
|
||
9.2.2 IF Masks INTR
|
||
9.2.3 RF Masks Debug Faults
|
||
9.2.4 MOV or POP to SS Masks Some Interrupts and Exceptions
|
||
|
||
9.3 Priority Among Simultaneous Interrupts and Exceptions
|
||
9.4 Interrupt Descriptor Table
|
||
9.5 IDT Descriptors
|
||
9.6 Interrupt Tasks and Interrupt Procedures
|
||
9.6.1 Interrupt Procedures
|
||
9.6.1.1 Stack of Interrupt Procedure
|
||
9.6.1.2 Returning from an Interrupt Procedure
|
||
9.6.1.3 Flags Usage by Interrupt Procedure
|
||
9.6.1.4 Protection in Interrupt Procedures
|
||
|
||
9.6.2 Interrupt Tasks
|
||
|
||
9.7 Error Code
|
||
9.8 Exception Conditions
|
||
9.8.1 Interrupt 0 ÄÄ Divide Error
|
||
9.8.2 Interrupt 1 ÄÄ Debug Exceptions
|
||
9.8.3 Interrupt 3 ÄÄ Breakpoint
|
||
9.8.4 Interrupt 4 ÄÄ Overflow
|
||
9.8.5 Interrupt 5 ÄÄ Bounds Check
|
||
9.8.6 Interrupt 6 ÄÄ Invalid Opcode
|
||
9.8.7 Interrupt 7 ÄÄ Coprocessor Not Available
|
||
9.8.8 Interrupt 8 ÄÄ Double Fault
|
||
9.8.9 Interrupt 9 ÄÄ Coprocessor Segment Overrun
|
||
9.8.10 Interrupt 10 ÄÄ Invalid TSS
|
||
9.8.11 Interrupt 11 ÄÄ Segment Not Present
|
||
9.8.12 Interrupt 12 ÄÄ Stack Exception
|
||
9.8.13 Interrupt 13 ÄÄ General Protection Exception
|
||
9.8.14 Interrupt 14 ÄÄ Page Fault
|
||
9.8.14.1 Page Fault during Task Switch
|
||
9.8.14.2 Page Fault with Inconsistent Stack Pointer
|
||
|
||
9.8.15 Interrupt 16 ÄÄ Coprocessor Error
|
||
|
||
9.9 Exception Summary
|
||
|
||
9.10 Error Code Summary
|
||
|
||
Chapter 10 Initialization
|
||
|
||
10.1 Processor State after Reset
|
||
10.2 Software Initialization for Real-Address Mode
|
||
10.2.1 Stack
|
||
10.2.2 Interrupt Table
|
||
10.2.3 First Instructions
|
||
|
||
10.3 Switching to Protected Mode
|
||
10.4 Software Initialization for Protected Mode
|
||
10.4.1 Interrupt Descriptor Table
|
||
10.4.2 Stack
|
||
10.4.3 Global Descriptor Table
|
||
10.4.4 Page Tables
|
||
10.4.5 First Task
|
||
|
||
10.5 Initialization Example
|
||
10.6 TLB Testing
|
||
10.6.1 Structure of the TLB
|
||
10.6.2 Test Registers
|
||
10.6.3 Test Operations
|
||
|
||
Chapter 11 Coprocessing and Multiprocessing
|
||
|
||
11.1 Coprocessing
|
||
11.1.1 Coprocessor Identification
|
||
11.1.2 ESC and WAIT Instructions
|
||
11.1.3 EM and MP Flags
|
||
11.1.4 The Task-Switched Flag
|
||
11.1.5 Coprocessor Exceptions
|
||
11.1.5.1 Interrupt 7 ÄÄ Coprocessor Not Available
|
||
11.1.5.2 Interrupt 9 ÄÄ Coprocessor Segment Overrun
|
||
11.1.5.3 Interrupt 16 ÄÄ Coprocessor Error
|
||
|
||
11.2 General Multiprocessing
|
||
11.2.1 LOCK and the LOCK# Signal
|
||
11.2.2 Automatic Locking
|
||
11.2.3 Cache Considerations
|
||
|
||
Chapter 12 Debugging
|
||
|
||
12.1 Debugging Features of the Architecture
|
||
12.2 Debug Registers
|
||
12.2.1 Debug Address Registers (DRO-DR3)
|
||
12.2.2 Debug Control Register (DR7)
|
||
12.2.3 Debug Status Register (DR6)
|
||
12.2.4 Breakpoint Field Recognition
|
||
|
||
12.3 Debug Exceptions
|
||
12.3.1 Interrupt 1 ÄÄ Debug Exceptions
|
||
12.3.1.1 Instruction Address Breakpoint
|
||
12.3.1.2 Data Address Breakpoint
|
||
12.3.1.3 General Detect Fault
|
||
12.3.1.4 Single-Step Trap
|
||
12.3.1.5 Task Switch Breakpoint
|
||
|
||
12.3.2 Interrupt 3 ÄÄ Breakpoint Exception
|
||
|
||
PART III COMPATIBILITY
|
||
|
||
Chapter 13 Executing 80286 Protected-Mode Code
|
||
|
||
13.1 80286 Code Executes as a Subset of the 80386
|
||
13.2 Two Ways to Execute 80286 Tasks
|
||
13.3 Differences from 80286
|
||
13.3.1 Wraparound of 80286 24-Bit Physical Address Space
|
||
13.3.2 Reserved Word of Descriptor
|
||
13.3.3 New Descriptor Type Codes
|
||
13.3.4 Restricted Semantics of LOCK
|
||
13.3.5 Additional Exceptions
|
||
|
||
Chapter 14 80386 Real-Address Mode
|
||
|
||
14.1 Physical Address Formation
|
||
14.2 Registers and Instructions
|
||
14.3 Interrupt and Exception Handling
|
||
14.4 Entering and Leaving Real-Address Mode
|
||
14.4.1 Switching to Protected Mode
|
||
|
||
14.5 Switching Back to Real-Address Mode
|
||
14.6 Real-Address Mode Exceptions
|
||
14.7 Differences from 8086
|
||
14.8 Differences from 80286 Real-Address Mode
|
||
14.8.1 Bus Lock
|
||
14.8.2 Location of First Instruction
|
||
14.8.3 Initial Values of General Registers
|
||
14.8.4 MSW Initialization
|
||
|
||
Chapter 15 Virtual 8088 Mode
|
||
|
||
15.1 Executing 8086 Code
|
||
15.1.1 Registers and Instructions
|
||
15.1.2 Linear Address Formation
|
||
|
||
15.2 Structure of a V86 Task
|
||
15.2.1 Using Paging for V86 Tasks
|
||
15.2.2 Protection within a V86 Task
|
||
|
||
15.3 Entering and Leaving V86 Mode
|
||
15.3.1 Transitions Through Task Switches
|
||
15.3.2 Transitions Through Trap Gates and Interrupt Gates
|
||
|
||
15.4 Additional Sensitive Instructions
|
||
15.4.1 Emulating 8086 Operating System Calls
|
||
15.4.2 Virtualizing the Interrupt-Enable Flag
|
||
|
||
15.5 Virtual I/O
|
||
15.5.1 I/O-Mapped I/O
|
||
15.5.2 Memory-Mapped I/O
|
||
15.5.3 Special I/O Buffers
|
||
|
||
15.6 Differences from 8086
|
||
15.7 Differences from 80286 Real-Address Mode
|
||
|
||
Chapter 16 Mixing 16-Bit and 32-Bit Code
|
||
|
||
16.1 How the 80386 Implements 16-Bit and 32-Bit Features
|
||
16.2 Mixing 32-Bit and 16-Bit Operations
|
||
16.3 Sharing Data Segments among Mixed Code Segments
|
||
16.4 Transferring Control among Mixed Code Segments
|
||
16.4.1 Size of Code-Segment Pointer
|
||
16.4.2 Stack Management for Control Transfers
|
||
16.4.2.1 Controlling the Operand-Size for a CALL
|
||
16.4.2.2 Changing Size of Call
|
||
|
||
16.4.3 Interrupt Control Transfers
|
||
16.4.4 Parameter Translation
|
||
16.4.5 The Interface Procedure
|
||
|
||
PART IV INSTRUCTION SET
|
||
|
||
Chapter 17 80386 Instruction Set
|
||
|
||
17.1 Operand-Size and Address-Size Attributes
|
||
17.1.1 Default Segment Attribute
|
||
17.1.2 Operand-Size and Address-Size Instruction Prefixes
|
||
17.1.3 Address-Size Attribute for Stack
|
||
|
||
17.2 Instruction Format
|
||
17.2.1 ModR/M and SIB Bytes
|
||
17.2.2 How to Read the Instruction Set Pages
|
||
17.2.2.1 Opcode
|
||
17.2.2.2 Instruction
|
||
17.2.2.3 Clocks
|
||
17.2.2.4 Description
|
||
17.2.2.5 Operation
|
||
17.2.2.6 Description
|
||
17.2.2.7 Flags Affected
|
||
17.2.2.8 Protected Mode Exceptions
|
||
17.2.2.9 Real Address Mode Exceptions
|
||
17.2.2.10 Virtual-8086 Mode Exceptions
|
||
|
||
Instruction Sets
|
||
|
||
AAA
|
||
AAD
|
||
AAM
|
||
AAS
|
||
ADC
|
||
ADD
|
||
AND
|
||
ARPL
|
||
BOUND
|
||
BSF
|
||
BSR
|
||
BT
|
||
BTC
|
||
BTR
|
||
BTS
|
||
CALL
|
||
CBW/CWDE
|
||
CLC
|
||
CLD
|
||
CLI
|
||
CLTS
|
||
CMC
|
||
CMP
|
||
CMPS/CMPSB/CMPSW/CMPSD
|
||
CWD/CDQ
|
||
DAA
|
||
DAS
|
||
DEC
|
||
DIV
|
||
ENTER
|
||
HLT
|
||
IDIV
|
||
IMUL
|
||
IN
|
||
INC
|
||
INS/INSB/INSW/INSD
|
||
INT/INTO
|
||
IRET/IRETD
|
||
Jcc
|
||
JMP
|
||
LAHF
|
||
LAR
|
||
LEA
|
||
LEAVE
|
||
LGDT/LIDT
|
||
LGS/LSS/LDS/LES/LFS
|
||
LLDT
|
||
LMSW
|
||
LOCK
|
||
LODS/LODSB/LODSW/LODSD
|
||
LOOP/LOOPcond
|
||
LSL
|
||
LTR
|
||
MOV
|
||
MOV
|
||
MOVS/MOVSB/MOVSW/MOVSD
|
||
MOVSX
|
||
MOVZX
|
||
MUL
|
||
NEG
|
||
NOP
|
||
NOT
|
||
OR
|
||
OUT
|
||
OUTS/OUTSB/OUTSW/OUTSD
|
||
POP
|
||
POPA/POPAD
|
||
POPF/POPFD
|
||
PUSH
|
||
PUSHA/PUSHAD
|
||
PUSHF/PUSHFD
|
||
RCL/RCR/ROL/ROR
|
||
REP/REPE/REPZ/REPNE/REPNZ
|
||
RET
|
||
SAHF
|
||
SAL/SAR/SHL/SHR
|
||
SBB
|
||
SCAS/SCASB/SCASW/SCASD
|
||
SETcc
|
||
SGDT/SIDT
|
||
SHLD
|
||
SHRD
|
||
SLDT
|
||
SMSW
|
||
STC
|
||
STD
|
||
STI
|
||
STOS/STOSB/STOSW/STOSD
|
||
STR
|
||
SUB
|
||
TEST
|
||
VERR,VERW
|
||
WAIT
|
||
XCHG
|
||
XLAT/XLATB
|
||
XOR
|
||
|
||
Appendix A Opcode Map
|
||
|
||
Appendix B Complete Flag Cross-Reference
|
||
|
||
Appendix C Status Flag Summary
|
||
|
||
Appendix D Condition Codes
|
||
|
||
|
||
Figures
|
||
|
||
1-1 Example Data Structure
|
||
|
||
2-1 Two-Component Pointer
|
||
2-2 Fundamental Data Types
|
||
2-3 Bytes, Words, and Doublewords in Memory
|
||
2-4 80386 Data Types
|
||
2-5 80386 Applications Register Set
|
||
2-6 Use of Memory Segmentation
|
||
2-7 80386 Stack
|
||
2-8 EFLAGS Register
|
||
2-9 Instruction Pointer Register
|
||
2-10 Effective Address Computation
|
||
|
||
3-1 PUSH
|
||
3-2 PUSHA
|
||
3-3 POP
|
||
3-4 POPA
|
||
3-5 Sign Extension
|
||
3-6 SAL and SHL
|
||
3-7 SHR
|
||
3-8 SAR
|
||
3-9 Using SAR to Simulate IDIV
|
||
3-10 Shift Left Double
|
||
3-11 Shift Right Double
|
||
3-12 ROL
|
||
3-13 ROR
|
||
3-14 RCL
|
||
3-15 RCR
|
||
3-16 Formal Definition of the ENTER Instruction
|
||
3-17 Variable Access in Nested Procedures
|
||
3-18 Stack Frame for MAIN at Level 1
|
||
3-19 Stack Frame for Prooedure A
|
||
3-20 Stack Frame for Procedure B at Level 3 Called from A
|
||
3-21 Stack Frame for Procedure C at Level 3 Called from B
|
||
3-22 LAHF and SAHF
|
||
3-23 Flag Format for PUSHF and POPF
|
||
|
||
4-1 Systems Flags of EFLAGS Register
|
||
4-2 Control Registers
|
||
|
||
5-1 Address Translation Overview
|
||
5-2 Segment Translation
|
||
5-3 General Segment-Descriptor Format
|
||
5-4 Format of Not-Present Descriptor
|
||
5-5 Descriptor Tables
|
||
5-6 Format of a Selector
|
||
5-7 Segment Registers
|
||
5-8 Format of a Linear Address
|
||
5-9 Page Translation
|
||
5-10 Format of a Page Table Entry
|
||
5-11 Invalid Page Table Entry
|
||
5-12 80386 Addressing Mechanism
|
||
5-13 Descriptor per Page Table
|
||
|
||
6-1 Protection Fields of Segment Descriptors
|
||
6-2 Levels of Privilege
|
||
6-3 Privilege Check for Data Access
|
||
6-4 Privilege Check for Control Transfer without Gate
|
||
6-5 Format of 80386 Call Gate
|
||
6-6 Indirect Transfer via Call Gate
|
||
6-7 Privilege Check via Call Gate
|
||
6-8 Initial Stack Pointers of TSS
|
||
6-9 Stack Contents after an Interievel Call
|
||
6-10 Protection Fields of Page Table Entries
|
||
|
||
7-1 80386 32-Bit Task State Segment
|
||
7-2 TSS Descriptor for 32-Bit TSS
|
||
7-3 Task Register
|
||
7-4 Task Gate Descriptor
|
||
7-5 Task Gate Indirectly Identifies Task
|
||
7-6 Partially-Overlapping Linear Spaces
|
||
|
||
8-1 Memory-Mapped I/O
|
||
8-2 I/O Address Bit Map
|
||
|
||
9-1 IDT Register and Table
|
||
9-2 Pseudo-Descriptor Format for LIDT and SIDT
|
||
9-3 80386 IDT Gate Descriptors
|
||
9-4 Interrupt Vectoring for Procedures
|
||
9-5 Stack Layout after Exception of Interrupt
|
||
9-6 Interrupt Vectoring for Tasks
|
||
9-7 Error Code Format
|
||
9-8 Page-Fault Error Code Format
|
||
9-9 CR2 Format
|
||
|
||
10-1 Contents of EDX after RESET
|
||
10-2 Initial Contents of CRO
|
||
10-3 TLB Structure
|
||
10-4 Test Registers
|
||
|
||
12-1 Debug Registers
|
||
|
||
14-1 Real-Address Mode Address Formation
|
||
|
||
15-1 V86 Mode Address Formation
|
||
15-2 Entering and Leaving an 8086 Program
|
||
15-3 PL 0 Stack after Interrupt in V86 Task
|
||
|
||
16-1 Stack after Far 16-Bit and 32-Bit Calls
|
||
|
||
17-1 80386 Instruction Format
|
||
17-2 ModR/M and SIB Byte Formats
|
||
17-3 Bit Offset for BIT[EAX, 21]
|
||
17-4 Memory Bit Indexing
|
||
|
||
|
||
Tables
|
||
|
||
2-1 Default Segment Register Selection Rules
|
||
2-2 80386 Reserved Exceptions and Interrupts
|
||
|
||
3-1 Bit Test and Modify Instructions
|
||
3-2 Interpretation of Conditional Transfers
|
||
|
||
6-1 System and Gate Descriptor Types
|
||
6-2 Useful Combinations of E, G, and B Bits
|
||
6-3 Interievel Return Checks
|
||
6-4 Valid Descriptor Types for LSL
|
||
6-5 Combining Directory and Page Protection
|
||
|
||
7-1 Checks Made during a Task Switch
|
||
7-2 Effect of Task Switch on BUSY, NT, and Back-Link
|
||
|
||
9-1 Interrupt and Exception ID Assignments
|
||
9-2 Priority Among Simultaneous Interrupts and Exceptions
|
||
9-3 Double-Fault Detection Classes
|
||
9-4 Double-Fault Definition
|
||
9-5 Conditions That Invalidate the TSS
|
||
9-6 Exception Summary
|
||
9-7 Error-Code Summary
|
||
|
||
10-1 Meaning of D, U, and W Bit Pairs
|
||
|
||
12-1 Breakpeint Field Recognition Examples
|
||
12-2 Debug Exception Conditions
|
||
|
||
14-1 80386 Real-Address Mode Exceptions
|
||
14-2 New 80386 Exceptions
|
||
|
||
17-1 Effective Size Attributes
|
||
17-2 16-Bit Addressing Forms with the ModR/M Byte
|
||
17-3 32-Bit Addressing Forms with the ModR/M Byte
|
||
17-4 32-Bit Addressing Forms with the SIB Byte
|
||
17-5 Task Switch Times for Exceptions
|
||
17-6 80386 Exceptions
|
||
|
||
|
||
Chapter 1 Introduction to the 80386
|
||
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
The 80386 is an advanced 32-bit microprocessor optimized for multitasking
|
||
operating systems and designed for applications needing very high
|
||
performance. The 32-bit registers and data paths support 32-bit addresses
|
||
and data types. The processor can address up to four gigabytes of physical
|
||
memory and 64 terabytes (2^(46) bytes) of virtual memory. The on-chip
|
||
memory-management facilities include address translation registers,
|
||
advanced multitasking hardware, a protection mechanism, and paged virtual
|
||
memory. Special debugging registers provide data and code breakpoints even
|
||
in ROM-based software.
|
||
|
||
|
||
1.1 Organization of This Manual
|
||
|
||
This book presents the architecture of the 80386 in five parts:
|
||
|
||
Part I ÄÄ Applications Programming
|
||
Part II ÄÄ Systems Programming
|
||
Part III ÄÄ Compatibility
|
||
Part IV ÄÄ Instruction Set
|
||
Appendices
|
||
|
||
These divisions are determined in part by the architecture itself and in
|
||
part by the different ways the book will be used. As the following table
|
||
indicates, the latter two parts are intended as reference material for
|
||
programmers actually engaged in the process of developing software for the
|
||
80386. The first three parts are explanatory, showing the purpose of
|
||
architectural features, developing terminology and concepts, and describing
|
||
instructions as they relate to specific purposes or to specific
|
||
architectural features.
|
||
|
||
Explanation Part I ÄÄ Applications Programming
|
||
Part II ÄÄ Systems Programming
|
||
Part III ÄÄ Compatibility
|
||
|
||
Reference Part IV ÄÄ Instruction Set
|
||
Appendices
|
||
|
||
The first three parts follow the execution modes and protection features of
|
||
the 80386 CPU. The distinction between applications features and systems
|
||
features is determined by the protection mechanism of the 80386. One purpose
|
||
of protection is to prevent applications from interfering with the operating
|
||
system; therefore, the processor makes certain registers and instructions
|
||
inaccessible to applications programs. The features discussed in Part I are
|
||
those that are accessible to applications; the features in Part II are
|
||
available only to systems software that has been given special privileges or
|
||
in unprotected systems.
|
||
|
||
The processing mode of the 80386 also determines the features that are
|
||
accessible. The 80386 has three processing modes:
|
||
|
||
1. Protected Mode.
|
||
2. Real-Address Mode.
|
||
3. Virtual 8086 Mode.
|
||
|
||
Protected mode is the natural 32-bit environment of the 80386 processor. In
|
||
this mode all instructions and features are available.
|
||
|
||
Real-address mode (often called just "real mode") is the mode of the
|
||
processor immediately after RESET. In real mode the 80386 appears to
|
||
programmers as a fast 8086 with some new instructions. Most applications of
|
||
the 80386 will use real mode for initialization only.
|
||
|
||
Virtual 8086 mode (also called V86 mode) is a dynamic mode in the sense
|
||
that the processor can switch repeatedly and rapidly between V86 mode and
|
||
protected mode. The CPU enters V86 mode from protected mode to execute an
|
||
8086 program, then leaves V86 mode and enters protected mode to continue
|
||
executing a native 80386 program.
|
||
|
||
The features that are available to applications programs in protected mode
|
||
and to all programs in V86 mode are the same. These features form the
|
||
content of Part I. The additional features that are available to systems
|
||
software in protected mode form Part II. Part III explains real-address
|
||
mode and V86 mode, as well as how to execute a mix of 32-bit and 16-bit
|
||
programs.
|
||
|
||
Available in All Modes Part I ÄÄ Applications Programming
|
||
|
||
Available in Protected Part II ÄÄ Systems Programming
|
||
Mode Only
|
||
|
||
Compatibility Modes Part III ÄÄ Compatibility
|
||
|
||
|
||
1.1.1 Part I ÄÄ Applications Programming
|
||
|
||
This part presents those aspects of the architecture that are customarily
|
||
used by applications programmers.
|
||
|
||
Chapter 2 ÄÄ Basic Programming Model: Introduces the models of memory
|
||
organization. Defines the data types. Presents the register set used by
|
||
applications. Introduces the stack. Explains string operations. Defines the
|
||
parts of an instruction. Explains addressing calculations. Introduces
|
||
interrupts and exceptions as they may apply to applications programming.
|
||
|
||
Chapter 3 ÄÄ Application Instruction Set: Surveys the instructions commonly
|
||
used for applications programming. Considers instructions in functionally
|
||
related groups; for example, string instructions are considered in one
|
||
section, while control-transfer instructions are considered in another.
|
||
Explains the concepts behind the instructions. Details of individual
|
||
instructions are deferred until Part IV, the instruction-set reference.
|
||
|
||
|
||
1.1.2 Part II ÄÄ Systems Programming
|
||
|
||
This part presents those aspects of the architecture that are customarily
|
||
used by programmers who write operating systems, device drivers, debuggers,
|
||
and other software that supports applications programs in the protected mode
|
||
of the 80386.
|
||
|
||
Chapter 4 ÄÄ Systems Architecture: Surveys the features of the 80386 that
|
||
are used by systems programmers. Introduces the remaining registers and data
|
||
structures of the 80386 that were not discussed in Part I. Introduces the
|
||
systems-oriented instructions in the context of the registers and data
|
||
structures they support. Points to the chapter where each register, data
|
||
structure, and instruction is considered in more detail.
|
||
|
||
Chapter 5 ÄÄ Memory Management: Presents details of the data structures,
|
||
registers, and instructions that support virtual memory and the concepts of
|
||
segmentation and paging. Explains how systems designers can choose a model
|
||
of memory organization ranging from completely linear ("flat") to fully
|
||
paged and segmented.
|
||
|
||
Chapter 6 ÄÄ Protection: Expands on the memory management features of the
|
||
80386 to include protection as it applies to both segments and pages.
|
||
Explains the implementation of privilege rules, stack switching, pointer
|
||
validation, user and supervisor modes. Protection aspects of multitasking
|
||
are deferred until the following chapter.
|
||
|
||
Chapter 7 ÄÄ Multitasking: Explains how the hardware of the 80386 supports
|
||
multitasking with context-switching operations and intertask protection.
|
||
|
||
Chapter 8 ÄÄ Input/Output: Reveals the I/O features of the 80386, including
|
||
I/O instructions, protection as it relates to I/O, and the I/O permission
|
||
map.
|
||
|
||
Chapter 9 ÄÄ Exceptions and Interrupts: Explains the basic interrupt
|
||
mechanisms of the 80386. Shows how interrupts and exceptions relate to
|
||
protection. Discusses all possible exceptions, listing causes and including
|
||
information needed to handle and recover from the exception.
|
||
|
||
Chapter 10 ÄÄ Initialization: Defines the condition of the processor after
|
||
RESET or power-up. Explains how to set up registers, flags, and data
|
||
structures for either real-address mode or protected mode. Contains an
|
||
example of an initialization program.
|
||
|
||
Chapter 11 ÄÄ Coprocessing and Multiprocessing: Explains the instructions
|
||
and flags that support a numerics coprocessor and multiple CPUs with shared
|
||
memory.
|
||
|
||
Chapter 12 ÄÄ Debugging: Tells how to use the debugging registers of the
|
||
80386.
|
||
|
||
|
||
1.1.3 Part III ÄÄ Compatibility
|
||
|
||
Other parts of the book treat the processor primarily as a 32-bit machine,
|
||
omitting for simplicity its facilities for 16-bit operations. Indeed, the
|
||
80386 is a 32-bit machine, but its design fully supports 16-bit operands and
|
||
addressing, too. This part completes the picture of the 80386 by explaining
|
||
the features of the architecture that support 16-bit programs and 16-bit
|
||
operations in 32-bit programs. All three processor modes are used to
|
||
execute 16-bit programs: protected mode can directly execute 16-bit 80286
|
||
protected mode programs, real mode executes 8086 programs and real-mode
|
||
80286 programs, and virtual 8086 mode executes 8086 programs in a
|
||
multitasking environment with other 80386 protected-mode programs. In
|
||
addition, 32-bit and 16-bit modules and individual 32-bit and 16-bit
|
||
operations can be mixed in protected mode.
|
||
|
||
Chapter 13 ÄÄ Executing 80286 Protected-Mode Code: In its protected mode,
|
||
the 80386 can execute complete 80286 protected-mode systems, because 80286
|
||
capabilities are a subset of 80386 capabilities.
|
||
|
||
Chapter 14 ÄÄ 80386 Real-Address Mode: Explains the real mode of the 80386
|
||
CPU. In this mode the 80386 appears as a fast real-mode 80286 or fast 8086
|
||
enhanced with additional instructions.
|
||
|
||
Chapter 15 ÄÄ Virtual 8086 Mode: The 80386 can switch rapidly between its
|
||
protected mode and V86 mode, giving it the ability to multiprogram 8086
|
||
programs along with "native mode" 32-bit programs.
|
||
|
||
Chapter 16 ÄÄ Mixing 16-Bit and 32-Bit Code: Even within a program or task,
|
||
the 80386 can mix 16-bit and 32-bit modules. Furthermore, any given module
|
||
can utilize both 16-bit and 32-bit operands and addresses.
|
||
|
||
|
||
1.1.4 Part IV ÄÄ Instruction Set
|
||
|
||
Parts I, II, and III present overviews of the instructions as they relate
|
||
to specific aspects of the architecture, but this part presents the
|
||
instructions in alphabetical order, providing the detail needed by
|
||
assembly-language programmers and programmers of debuggers, compilers,
|
||
operating systems, etc. Instruction descriptions include algorithmic
|
||
description of operation, effect of flag settings, effect on flag settings,
|
||
effect of operand- or address-size attributes, effect of processor modes,
|
||
and possible exceptions.
|
||
|
||
|
||
1.1.5 Appendices
|
||
|
||
The appendices present tables of encodings and other details in a format
|
||
designed for quick reference by assembly-language and systems programmers.
|
||
|
||
|
||
1.2 Related Literature
|
||
|
||
The following books contain additional material concerning the 80386
|
||
microprocessor:
|
||
|
||
þ Introduction to the 80386, order number 231252
|
||
|
||
þ 80386 Hardware Reference Manual, order number 231732
|
||
|
||
þ 80386 System Software Writer's Guide, order number 231499
|
||
|
||
þ 80386 High Performance 32-bit Microprocessor with Integrated Memory
|
||
Management (Data Sheet), order number 231630
|
||
|
||
|
||
1.3 Notational Conventions
|
||
|
||
This manual uses special notations for data-structure formats, for symbolic
|
||
representation of instructions, for hexadecimal numbers, and for super- and
|
||
sub-scripts. 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. A review of these notations will make it easier to read the
|
||
manual.
|
||
|
||
1.3.1 Data-Structure Formats
|
||
|
||
In illustrations of data structures in memory, smaller addresses appear at
|
||
the lower-right part of the figure; addresses increase toward the left and
|
||
upwards. Bit positions are numbered from right to left. Figure 1-1
|
||
illustrates this convention.
|
||
|
||
|
||
1.3.2 Undefined Bits and Software Compatibility
|
||
|
||
In many register and memory layout descriptions, certain bits are marked as
|
||
undefined. When bits are marked as undefined (as illustrated in Figure
|
||
1-1), it is essential for compatibility with future processors that
|
||
software treat these bits as undefined. Software should follow these
|
||
guidelines in dealing with undefined bits:
|
||
|
||
þ Do not depend on the states of any undefined bits when testing the
|
||
values of registers that contain such bits. Mask out the undefined bits
|
||
before testing.
|
||
|
||
þ Do not depend on the states of any undefined bits when storing them in
|
||
memory or in another register.
|
||
|
||
þ Do not depend on the ability to retain information written into any
|
||
undefined bits.
|
||
|
||
þ When loading a register, always load the undefined bits as zeros or
|
||
reload them with values previously stored from the same register.
|
||
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
NOTE
|
||
Depending upon the values of undefined register bits will make software
|
||
dependent upon the unspecified manner in which the 80386 handles these
|
||
bits. Depending upon undefined values risks making software incompatible
|
||
with future processors that define usages for these bits. AVOID ANY
|
||
SOFTWARE DEPENDENCE UPON THE STATE OF UNDEFINED 80386 REGISTER BITS.
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
|
||
Figure 1-1. Example Data Structure
|
||
|
||
GREATEST DATA STRUCTURE
|
||
ADDRESS
|
||
31 23 15 7 0 ÄÄBIT
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» OFFSET
|
||
º º28
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
º º24
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
º º20
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
º º16
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
º º12
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
º º8
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
º UNDEFINED º4
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ SMALLEST
|
||
º BYTE 3 BYTE 2 BYTE 1 BYTE 0 º0 ADDRESS
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
BYTE OFFSETÄÄÄÙ
|
||
|
||
|
||
1.3.3 Instruction Operands
|
||
|
||
When instructions are represented symbolically, a subset of the 80386
|
||
Assembly Language is used. In this subset, an instruction has the following
|
||
format:
|
||
|
||
label: prefix mnemonic argument1, argument2, argument3
|
||
|
||
where:
|
||
|
||
þ A label is an identifier that is followed by a colon.
|
||
|
||
þ A prefix is an optional reserved name for one of the instruction
|
||
prefixes.
|
||
|
||
þ A mnemonic is a reserved name for a class of instruction opcodes that
|
||
have the same function.
|
||
|
||
þ The operands argument1, argument2, and argument3 are optional. There
|
||
may be from zero to three operands, depending on the opcode. When
|
||
present, they take the form of either literals or identifiers for data
|
||
items. Operand identifiers are either reserved names of registers or
|
||
are assumed to be assigned to data items declared in another part of
|
||
the program (which may not be shown in the example). When two operands
|
||
are present in an instruction that modifies data, the right operand is
|
||
the source and the left operand is the destination.
|
||
|
||
For example:
|
||
|
||
LOADREG: MOV EAX, SUBTOTAL
|
||
|
||
In this example LOADREG is a label, MOV is the mnemonic identifier of an
|
||
opcode, EAX is the destination operand, and SUBTOTAL is the source operand.
|
||
|
||
1.3.4 Hexadecimal Numbers
|
||
|
||
Base 16 numbers are represented by a string of hexadecimal digits followed
|
||
by the character H. A hexadecimal digit is a character from the set (0, 1,
|
||
2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F). In some cases, especially in
|
||
examples of program syntax, a leading zero is added if the number would
|
||
otherwise begin with one of the digits A-F. For example, 0FH is equivalent
|
||
to the decimal number 15.
|
||
|
||
1.3.5 Sub- and Super-Scripts
|
||
|
||
This manual uses special notation to represent sub- and super-script
|
||
characters. Sub-script characters are surrounded by {curly brackets}, for
|
||
example 10{2} = 10 base 2. Super-script characters are preceeded by a
|
||
caret and enclosed within (parentheses), for example 10^(3) = 10 to the
|
||
third power.
|
||
|
||
|
||
PART I APPLICATIONS PROGRAMMING
|
||
|
||
|
||
Chapter 2 Basic Programming Model
|
||
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
This chapter describes the 80386 application programming environment as
|
||
seen by assembly language programmers when the processor is executing in
|
||
protected mode. The chapter introduces programmers to those features of the
|
||
80386 architecture that directly affect the design and implementation of
|
||
80386 applications programs. Other chapters discuss 80386 features that
|
||
relate to systems programming or to compatibility with other processors of
|
||
the 8086 family.
|
||
|
||
The basic programming model consists of these aspects:
|
||
|
||
þ Memory organization and segmentation
|
||
þ Data types
|
||
þ Registers
|
||
þ Instruction format
|
||
þ Operand selection
|
||
þ Interrupts and exceptions
|
||
|
||
Note that input/output is not included as part of the basic programming
|
||
model. Systems designers may choose to make I/O instructions available to
|
||
applications or may choose to reserve these functions for the operating
|
||
system. For this reason, the I/O features of the 80386 are discussed in Part
|
||
II.
|
||
|
||
This chapter contains a section for each aspect of the architecture that is
|
||
normally visible to applications.
|
||
|
||
|
||
2.1 Memory Organization and Segmentation
|
||
|
||
The physical memory of an 80386 system is organized as a sequence of 8-bit
|
||
bytes. Each byte is assigned a unique address that ranges from zero to a
|
||
maximum of 2^(32) -1 (4 gigabytes).
|
||
|
||
80386 programs, however, are independent of the physical address space.
|
||
This means that programs can be written without knowledge of how much
|
||
physical memory is available and without knowledge of exactly where in
|
||
physical memory the instructions and data are located.
|
||
|
||
The model of memory organization seen by applications programmers is
|
||
determined by systems-software designers. The architecture of the 80386
|
||
gives designers the freedom to choose a model for each task. The model of
|
||
memory organization can range between the following extremes:
|
||
|
||
þ A "flat" address space consisting of a single array of up to 4
|
||
gigabytes.
|
||
|
||
þ A segmented address space consisting of a collection of up to 16,383
|
||
linear address spaces of up to 4 gigabytes each.
|
||
|
||
Both models can provide memory protection. Different tasks may employ
|
||
different models of memory organization. The criteria that designers use to
|
||
determine a memory organization model and the means that systems programmers
|
||
use to implement that model are covered in Part IIÄÄSystems Programming.
|
||
|
||
|
||
2.1.1 The "Flat" Model
|
||
|
||
In a "flat" model of memory organization, the applications programmer sees
|
||
a single array of up to 2^(32) bytes (4 gigabytes). While the physical
|
||
memory can contain up to 4 gigabytes, it is usually much smaller; the
|
||
processor maps the 4 gigabyte flat space onto the physical address space by
|
||
the address translation mechanisms described in Chapter 5. Applications
|
||
programmers do not need to know the details of the mapping.
|
||
|
||
A pointer into this flat address space is a 32-bit ordinal number that may
|
||
range from 0 to 2^(32) -1. Relocation of separately-compiled modules in this
|
||
space must be performed by systems software (e.g., linkers, locators,
|
||
binders, loaders).
|
||
|
||
|
||
2.1.2 The Segmented Model
|
||
|
||
In a segmented model of memory organization, the address space as viewed by
|
||
an applications program (called the logical address space) is a much larger
|
||
space of up to 2^(46) bytes (64 terabytes). The processor maps the 64
|
||
terabyte logical address space onto the physical address space (up to 4
|
||
gigabytes) by the address translation mechanisms described in Chapter 5.
|
||
Applications programmers do not need to know the details of this mapping.
|
||
|
||
Applications programmers view the logical address space of the 80386 as a
|
||
collection of up to 16,383 one-dimensional subspaces, each with a specified
|
||
length. Each of these linear subspaces is called a segment. A segment is a
|
||
unit of contiguous address space. Segment sizes may range from one byte up
|
||
to a maximum of 2^(32) bytes (4 gigabytes).
|
||
|
||
A complete pointer in this address space consists of two parts (see Figure
|
||
2-1):
|
||
|
||
1. A segment selector, which is a 16-bit field that identifies a
|
||
segment.
|
||
|
||
2. An offset, which is a 32-bit ordinal that addresses to the byte level
|
||
within a segment.
|
||
|
||
During execution of a program, the processor associates with a segment
|
||
selector the physical address of the beginning of the segment. Separately
|
||
compiled modules can be relocated at run time by changing the base address
|
||
of their segments. The size of a segment is variable; therefore, a segment
|
||
can be exactly the size of the module it contains.
|
||
|
||
|
||
2.2 Data Types
|
||
|
||
Bytes, words, and doublewords are the fundamental data types (refer to
|
||
Figure 2-2). A byte is eight contiguous bits starting at any logical
|
||
address. The bits are numbered 0 through 7; bit zero is the least
|
||
significant bit.
|
||
|
||
A word is two contiguous bytes starting at any byte address. A word thus
|
||
contains 16 bits. The bits of a word are numbered from 0 through 15; bit 0
|
||
is the least 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.
|
||
|
||
Each byte within a word has its own address, and the smaller of the
|
||
addresses is 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.
|
||
|
||
A doubleword is two contiguous words starting at any byte address. A
|
||
doubleword thus contains 32 bits. The bits of a doubleword are numbered from
|
||
0 through 31; bit 0 is the least significant bit. The word containing bit 0
|
||
of the doubleword is called the low word; the word containing bit 31 is
|
||
called the high word.
|
||
|
||
Each byte within a doubleword has its own address, and the smallest of the
|
||
addresses is the address of the doubleword. The byte at this lowest address
|
||
contains the eight least significant bits of the doubleword, while the byte
|
||
at the highest address contains the eight most significant bits. Figure 2-3
|
||
illustrates the arrangement of bytes within words anddoublewords.
|
||
|
||
Note that words need not be aligned at even-numbered addresses and
|
||
doublewords need not be aligned at addresses evenly divisible by four. This
|
||
allows maximum flexibility in data structures (e.g., records containing
|
||
mixed byte, word, and doubleword items) and efficiency in memory
|
||
utilization. When used in a configuration with a 32-bit bus, actual
|
||
transfers of data between processor and memory take place in units of
|
||
doublewords beginning at addresses evenly divisible by four; however, the
|
||
processor converts requests for misaligned words or doublewords into the
|
||
appropriate sequences of requests acceptable to the memory interface. Such
|
||
misaligned data transfers reduce performance by requiring extra memory
|
||
cycles. For maximum performance, data structures (including stacks) should
|
||
be designed in such a way that, whenever possible, word operands are aligned
|
||
at even addresses and doubleword operands are aligned at addresses evenly
|
||
divisible by four. Due to instruction prefetching and queuing within the
|
||
CPU, there is no requirement for instructions to be aligned on word or
|
||
doubleword boundaries. (However, a slight increase in speed results if the
|
||
target addresses of control transfers are evenly divisible by four.)
|
||
|
||
Although bytes, words, and doublewords are the fundamental types of
|
||
operands, the processor also supports additional interpretations of these
|
||
operands. Depending on the instruction referring to the operand, the
|
||
following additional data types are recognized:
|
||
|
||
Integer:
|
||
A signed binary numeric value contained in a 32-bit doubleword,16-bit word,
|
||
or 8-bit byte. All operations assume a 2's complement representation. The
|
||
sign bit is located in bit 7 in a byte, bit 15 in a word, and bit 31 in a
|
||
doubleword. The sign bit has the value zero for positive integers and one
|
||
for negative. 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; 32-bit integers may range from -2^(31) through +2^(31) -1.
|
||
The value zero has a positive sign.
|
||
|
||
Ordinal:
|
||
An unsigned binary numeric value contained in a 32-bit doubleword,
|
||
16-bit word, or 8-bit byte. All bits are considered in determining
|
||
magnitude of the number. The value range of an 8-bit ordinal number
|
||
is 0-255; 16 bits can represent values from 0 through 65,535; 32 bits
|
||
can represent values from 0 through 2^(32) -1.
|
||
|
||
Near Pointer:
|
||
A 32-bit logical address. A near pointer is an offset within a segment.
|
||
Near pointers are used in either a flat or a segmented model of memory
|
||
organization.
|
||
|
||
Far Pointer:
|
||
A 48-bit logical address of two components: a 16-bit segment selector
|
||
component and a 32-bit offset component. Far pointers are used by
|
||
applications programmers only when systems designers choose a
|
||
segmented memory organization.
|
||
|
||
String:
|
||
A contiguous sequence of bytes, words, or doublewords. A string may
|
||
contain from zero bytes to 2^(32) -1 bytes (4 gigabytes).
|
||
|
||
Bit field:
|
||
A contiguous sequence of bits. A bit field may begin at any bit position
|
||
of any byte and may contain up to 32 bits.
|
||
|
||
Bit string:
|
||
A contiguous sequence of bits. A bit string may begin at any bit position
|
||
of any byte and may contain up to 2^(32) -1 bits.
|
||
|
||
BCD:
|
||
A byte (unpacked) representation of a decimal digit in the range0 through
|
||
9. 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.
|
||
|
||
Packed BCD:
|
||
A byte (packed) representation of two decimal digits, each in the range
|
||
0 through 9. One digit is stored in each half-byte. The digit in the
|
||
high-order half-byte is the most significant. Values 0-9 are valid in each
|
||
half-byte. The range of a packed decimal byte is 0-99.
|
||
|
||
Figure 2-4 graphically summarizes the data types supported by the 80386.
|
||
|
||
|
||
Figure 2-1. Two-Component Pointer
|
||
|
||
|
||
º º
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹Ŀ
|
||
32 0 º º ³
|
||
ÉÍÍÍÍÍÍÍØÍÍÍÍÍÍÍ» ÉÍÍÍ» ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ ³
|
||
º OFFSET ÇÄÄĶ + ÇÄÄĺ OPERAND º ³
|
||
ÈÍÍÍÍÍÍÍØÍÍÍÍÍÍͼ ÈÍÍͼ ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ ÃÄ SELECTED SEGMENT
|
||
º º ³
|
||
16 0 ³ º º ³
|
||
ÉÍÍÍÍÍÍÍ» ³ º º ³
|
||
ºSEGMENTÇÄÄÄÄÄÄÄÄÄùÄÄÄÄÄÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ÄÙ
|
||
ÈÍÍÍÍÍÍͼ º º
|
||
º º
|
||
º º
|
||
|
||
|
||
|
||
Figure 2-2. Fundamental Data Types
|
||
|
||
7 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º BYTE º BYTE
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
15 7 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º HIGH BYTE ³ LOW BYTE º WORD
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
address n+1 address n
|
||
|
||
31 23 15 7 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º HIGH WORD ³ LOW WORD º DOUBLEWORD
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
address n+3 address n+2 address n+1 address n
|
||
|
||
|
||
Figure 2-3. Bytes, Words, and Doublewords in Memory
|
||
|
||
MEMORY
|
||
BYTE VALUES
|
||
All values in hexadecimal
|
||
ADDRESS ÉÍÍÍÍÍÍÍÍÍÍ»
|
||
Eº º
|
||
ÌÍÍÍÍÍÍÍÍÍ͹ÄÄ¿
|
||
Dº 7A º ÃÄ DOUBLE WORD AT ADDRESS A
|
||
ÌÍÍÍÍÍÍÍÍÍ͹Ŀ³ CONTAINS 7AFE0636
|
||
Cº FE º ³³
|
||
ÌÍÍÍÍÍÍÍÍÍ͹ ÃÄ WORD AT ADDRESS B
|
||
Bº 06 º ³³ CONTAINS FE06
|
||
ÌÍÍÍÍÍÍÍÍÍ͹ÄÙ³
|
||
Aº 36 º ³
|
||
ÌÍÍÍÍÍÍÍÍÍ͹Í͵
|
||
9º 1F º ÃÄ WORD AT ADDRESS 9
|
||
ÌÍÍÍÍÍÍÍÍÍ͹ÄÄÙ CONTAINS IF
|
||
8º º
|
||
ÌÍÍÍÍÍÍÍÍÍ͹ÄÄ¿
|
||
7º 23 º ³
|
||
ÌÍÍÍÍÍÍÍÍÍ͹ ÃÄ WORD AT ADDRESS 6
|
||
6º OB º ³ CONTAINS 23OB
|
||
ÌÍÍÍÍÍÍÍÍÍ͹ÄÄÙ
|
||
5º º
|
||
ÌÍÍÍÍÍÍÍÍÍ͹
|
||
4º º
|
||
ÌÍÍÍÍÍÍÍÍÍ͹ÄÄ¿
|
||
3º 74 º ³
|
||
ÌÍÍÍÍÍÍÍÍÍ͹ĿÃÄ WORD AT ADDRESS 2
|
||
2º CB º ³³ CONTAINS 74CB
|
||
ÌÍÍÍÍÍÍÍÍÍ͹ÄÄÙ
|
||
1º 31 º ÃÄÄ WORD AT ADDRESS 1
|
||
ÌÍÍÍÍÍÍÍÍÍ͹ÄÙ CONTAINS CB31
|
||
0º º
|
||
ÈÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
|
||
Figure 2-4. 80386 Data Types
|
||
|
||
+1 0
|
||
7 0 7 0 15 14 8 7 0
|
||
BYTE ÉÑÑÑÑÑÑÑ» BYTE ÉÑÑÑÑÑÑÑ» WORD ÉÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ»
|
||
INTEGER º³ ³ º ORDINAL º ³ º INTEGER º³ ³ ³ ³ º
|
||
ÈÏÍÍÍÍÍͼ ÈÍÍÍÍÍÍͼ ÈÏÍÍÍÍÍÍÏÍÍÍÍÍÍͼ
|
||
SIGN BITÙÀÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÙ SIGN BITÙÀMSB ³
|
||
MAGNITUDE MAGNITUDE ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
||
MAGNITUDE
|
||
|
||
|
||
+1 0 +3 +2 +1 0
|
||
15 0 31 16 15 0
|
||
WORD ÉÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ» DOUBLEWORD ÉÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ»
|
||
ORDINAL º³ ³ ³ ³ º INTEGER º³ ³ ³ ³ ³ ³ ³ ³ º
|
||
ÈÏÍÍÍÍÍÍÏÍÍÍÍÍÍͼ ÈÏÍÍÍÍÍÍÏÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÏÍÍÍÍÍÍͼ
|
||
³ ³ SIGN BITÙÀMSB ³
|
||
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
||
MAGNITUDE MAGNITUDE
|
||
|
||
|
||
+3 +2 +1 0
|
||
31 0
|
||
DOUBLEWORD ÉÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ»
|
||
ORDINAL º ³ ³ ³ ³ ³ ³ ³ º
|
||
ÈÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÏÍÍÍÍÍÍͼ
|
||
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
||
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
|
||
PACKED ÉÑÑÑÑÑÑÑ» ÉÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ»
|
||
BCD º ³ º º ³ ³ ³ º
|
||
ÈÍÍÍÍÍÍͼ ÈÍÍÍÍÍÍÍÏÍÍÍÍÍÍͼ
|
||
ÀÄÄÄÙ ÀÄÄÄÙ
|
||
MOST LEAST
|
||
SIGNIFICANT SIGNIFICANT
|
||
DIGIT DIGIT
|
||
|
||
+N +1 0
|
||
7 0 7 0 7 0
|
||
BYTE ÉÑÑÑÑÑÑÑ» ÉÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ»
|
||
STRING º ³ º º ³ ³ ³ º
|
||
ÈÍÍÍÍÍÍͼ ÈÍÍÍÍÍÍÍÏÍÍÍÍÍÍͼ
|
||
|
||
-2 GIGABYTES
|
||
+2 GIGABYTES 210
|
||
BIT ÉÑÑÑÑÍÍÍÍÍÍÍÍÍÍÍÍÑÑÍÍÍÍÍÍÍ ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÑÑÑ»
|
||
STRING º³³³³ ³³ ³³³³º
|
||
ÈÏÏÏÏÍÍÍÍÍÍÍÍÍÍÍÍÏÏÍÍÍÍÍÍÍÍ ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÏÏϼ
|
||
BIT 0
|
||
|
||
+3 +2 +1 0
|
||
31 0
|
||
NEAR 32-BIT ÉÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ»
|
||
POINTER º ³ ³ ³ ³ ³ ³ ³ º
|
||
ÈÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÏÍÍÍÍÍÍͼ
|
||
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
||
OFFSET
|
||
|
||
+5 +4 +3 +2 +1 0
|
||
48 0
|
||
FAR 48-BIT ÉÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ»
|
||
POINTER º ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
||
ÈÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÏÍÍÍÍÍÍͼ
|
||
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
||
SELECTOR OFFSET
|
||
|
||
+5 +4 +3 +2 +1 0
|
||
32-BIT ÉÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ»
|
||
BIT FIELD º ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
||
ÈÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÏÍÍÍÍÍÍͼ
|
||
³ÄÄÄÄÄÄÄÄÄ BIT FIELD ÄÄÄÄÄÄÄÄij
|
||
1 TO 32 BITS
|
||
|
||
|
||
2.3 Registers
|
||
|
||
The 80386 contains a total of sixteen registers that are of interest to the
|
||
applications programmer. As Figure 2-5 shows, these registers may be
|
||
grouped into these basic categories:
|
||
|
||
1. General registers. These eight 32-bit general-purpose registers are
|
||
used primarily to contain operands for arithmetic and logical
|
||
operations.
|
||
|
||
2. Segment registers. These special-purpose registers permit systems
|
||
software designers to choose either a flat or segmented model of
|
||
memory organization. These six registers determine, at any given time,
|
||
which segments of memory are currently addressable.
|
||
|
||
3. Status and instruction registers. These special-purpose registers are
|
||
used to record and alter certain aspects of the 80386 processor state.
|
||
|
||
|
||
2.3.1 General Registers
|
||
|
||
The general registers of the 80386 are the 32-bit registers EAX, EBX, ECX,
|
||
EDX, EBP, ESP, ESI, and EDI. These registers are used interchangeably to
|
||
contain the operands of logical and arithmetic operations. They may also be
|
||
used interchangeably for operands of address computations (except that ESP
|
||
cannot be used as an index operand).
|
||
|
||
As Figure 2-5 shows, the low-order word of each of these eight registers
|
||
has a separate name and can be treated as a unit. This feature is useful for
|
||
handling 16-bit data items and for compatibility with the 8086 and 80286
|
||
processors. The word registers are named AX, BX, CX, DX, BP, SP, SI, and DI.
|
||
|
||
Figure 2-5 also illustrates that each byte of the 16-bit registers AX, BX,
|
||
CX, and DX has a separate name and can be treated as a unit. This feature is
|
||
useful for handling characters and other 8-bit data items. The byte
|
||
registers are named AH, BH, CH, and DH (high bytes); and AL, BL, CL, and DL
|
||
(low bytes).
|
||
|
||
All of the general-purpose registers are available for addressing
|
||
calculations and for the results of most arithmetic and logical
|
||
calculations; however, a few functions are dedicated to certain registers.
|
||
By implicitly choosing registers for these functions, the 80386 architecture
|
||
can encode instructions more compactly. The instructions that use specific
|
||
registers include: double-precision multiply and divide, I/O, string
|
||
instructions, translate, loop, variable shift and rotate, and stack
|
||
operations.
|
||
|
||
|
||
2.3.2 Segment Registers
|
||
|
||
The segment registers of the 80386 give systems software designers the
|
||
flexibility to choose among various models of memory organization.
|
||
Implementation of memory models is the subject of Part II ÄÄ Systems
|
||
Programming. Designers may choose a model in which applications programs do
|
||
not need to modify segment registers, in which case applications programmers
|
||
may skip this section.
|
||
|
||
Complete programs generally consist of many different modules, each
|
||
consisting of instructions and data. However, at any given time during
|
||
program execution, only a small subset of a program's modules are actually
|
||
in use. The 80386 architecture takes advantage of this by providing
|
||
mechanisms to support direct access to the instructions and data of the
|
||
current module's environment, with access to additional segments on demand.
|
||
|
||
At any given instant, six segments of memory may be immediately accessible
|
||
to an executing 80386 program. The segment registers CS, DS, SS, ES, FS, and
|
||
GS are used to identify these six current segments. Each of these registers
|
||
specifies a particular kind of segment, as characterized by the associated
|
||
mnemonics ("code," "data," or "stack") shown in Figure 2-6. Each register
|
||
uniquely determines one particular segment, from among the segments that
|
||
make up the program, that is to be immediately accessible at highest speed.
|
||
|
||
The segment containing the currently executing sequence of instructions is
|
||
known as the current code segment; it is specified by means of the CS
|
||
register. The 80386 fetches all instructions from this code segment, using
|
||
as an offset the contents of the instruction pointer. CS is changed
|
||
implicitly as the result of intersegment control-transfer instructions (for
|
||
example, CALL and JMP), interrupts, and exceptions.
|
||
|
||
Subroutine calls, parameters, and procedure activation records usually
|
||
require that a region of memory be allocated for a stack. All stack
|
||
operations use the SS register to locate the stack. Unlike CS, the SS
|
||
register can be loaded explicitly, thereby permitting programmers to define
|
||
stacks dynamically.
|
||
|
||
The DS, ES, FS, and GS registers allow the specification of four data
|
||
segments, each addressable by the currently executing program. Accessibility
|
||
to four separate data areas helps programs efficiently access different
|
||
types of data structures; for example, one data segment register can point
|
||
to the data structures of the current module, another to the exported data
|
||
of a higher-level module, another to a dynamically created data structure,
|
||
and another to data shared with another task. An operand within a data
|
||
segment is addressed by specifying its offset either directly in an
|
||
instruction or indirectly via general registers.
|
||
|
||
Depending on the structure of data (e.g., the way data is parceled into one
|
||
or more segments), a program may require access to more than four data
|
||
segments. To access additional segments, the DS, ES, FS, and GS registers
|
||
can be changed under program control during the course of a program's
|
||
execution. This simply requires that the program execute an instruction to
|
||
load the appropriate segment register prior to executing instructions that
|
||
access the data.
|
||
|
||
The processor associates a base address with each segment selected by a
|
||
segment register. To address an element within a segment, a 32-bit offset is
|
||
added to the segment's base address. Once a segment is selected (by loading
|
||
the segment selector into a segment register), a data manipulation
|
||
instruction only needs to specify the offset. Simple rules define which
|
||
segment register is used to form an address when only an offset is
|
||
specified.
|
||
|
||
|
||
Figure 2-5. 80386 Applications Register Set
|
||
|
||
GENERAL REGISTERS
|
||
|
||
31 23 15 7 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º EAX AH AX AL º
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
º EDX DH DX DL º
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
º ECX CH CX CL º
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
º EBX BH BX BL º
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
º EBP BP º
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
º ESI SI º
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
º EDI DI º
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
º ESP SP º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
|
||
15 7 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º CS (CODE SEGMENT) º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º SS (STACK SEGMENT) º
|
||
SEGMENT ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
REGISTERS º DS (DATA SEGMENT) º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º ES (DATA SEGMENT) º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º FS (DATA SEGMENT) º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º GS (DATA SEGMENT) º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
|
||
STATUS AND INSTRUCTION REGISTERS
|
||
|
||
31 23 15 7 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º EFLAGS º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º EIP (INSTRUCTION POINTER) º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
|
||
Figure 2-6. Use of Memory Segmentation
|
||
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º MODULE º º MODULE º
|
||
º A ºÄÄ¿ ÚÄĺ A º
|
||
º CODE º ³ ³ º DATA º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ ³ ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» ³ ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
ÀÄĶ CS (CODE) º ³
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ ³
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» ÚÄĶ SS (STACK) º ³ ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º º ³ ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ ³ º DATA º
|
||
º STACK ºÄÄÙ º DS (DATA) ÇÄÄÙÚĺ STRUCTURE º
|
||
º º ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ ³ º 1 º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ º ES (DATA) ÇÄÄÄÙ ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
ÚÄĶ FS (DATA) º
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» ³ ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º DATA º ³ º GS (DATA) ÇÄÄ¿ º DATA º
|
||
º STRUCTURE ºÄÄÙ ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ ÀÄĺ STRUCTURE º
|
||
º 2 º º 3 º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
|
||
2.3.3 Stack Implementation
|
||
|
||
Stack operations are facilitated by three registers:
|
||
|
||
1. The stack segment (SS) register. Stacks are implemented in memory. A
|
||
system may have a number of stacks that is limited only by the maximum
|
||
number of segments. A stack may be up to 4 gigabytes long, the maximum
|
||
length of a segment. One stack is directly addressable at a timeÄÄthe
|
||
one located by SS. This is the current stack, often referred to simply
|
||
as "the" stack. SS is used automatically by the processor for all
|
||
stack operations.
|
||
|
||
2. The stack pointer (ESP) register. ESP points to the top of the
|
||
push-down stack (TOS). It is referenced implicitly by PUSH and POP
|
||
operations, subroutine calls and returns, and interrupt operations.
|
||
When an item is pushed onto the stack (see Figure 2-7), the processor
|
||
decrements ESP, then writes the item at the new TOS. When an item is
|
||
popped off the stack, the processor copies it from TOS, then
|
||
increments ESP. In other words, the stack grows down in memory toward
|
||
lesser addresses.
|
||
|
||
3. The stack-frame base pointer (EBP) register. The EBP is the best
|
||
choice of register for accessing data structures, variables and
|
||
dynamically allocated work space within the stack. EBP 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. When EBP is used as the base register in an offset
|
||
calculation, the offset is calculated automatically in the current
|
||
stack segment (i.e., the segment currently selected by SS). Because
|
||
SS does not have to be explicitly specified, instruction encoding in
|
||
such cases is more efficient. EBP can also be used to index into
|
||
segments addressable via other segment registers.
|
||
|
||
|
||
Figure 2-7. 80386 Stack
|
||
|
||
31 0
|
||
ÉÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍ» ÄÄÄÄÄÄÄBOTTOM OF STACK
|
||
º º (INITIAL ESP VALUE)
|
||
ÇÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍ͹
|
||
º º
|
||
ÌÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍ͹
|
||
º º ³POP
|
||
ÌÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍ͹ ³
|
||
º º ³
|
||
ÌÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍ͹ ³ TOP OF ÉÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º º ÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ ESP º
|
||
ÌÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍ͹ ³ STACK ÈÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
º º ³
|
||
º º ³
|
||
º º ³PUSH
|
||
º º
|
||
|
||
|
||
2.3.4 Flags Register
|
||
|
||
The flags register is a 32-bit register named EFLAGS. Figure 2-8 defines
|
||
the bits within this register. The flags control certain operations and
|
||
indicate the status of the 80386.
|
||
|
||
The low-order 16 bits of EFLAGS is named FLAGS and can be treated as a
|
||
unit. This feature is useful when executing 8086 and 80286 code, because
|
||
this part of EFLAGS is identical to the FLAGS register of the 8086 and the
|
||
80286.
|
||
|
||
The flags may be considered in three groups: the status flags, the control
|
||
flags, and the systems flags. Discussion of the systems flags is delayed
|
||
until Part II.
|
||
|
||
|
||
Figure 2-8. EFLAGS Register
|
||
|
||
16-BIT FLAGS REGISTER
|
||
A
|
||
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
||
31 23 15 7 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÑÍÑÍÑÍÑÍØÍÑÍÑÍÑÍÑÍÑÍÑÍÑÍÑÍÑÍÑÍÑÍÑÍ»
|
||
º ³V³R³ ³N³ IO³O³D³I³T³S³Z³ ³A³ ³P³ ³Cº
|
||
º 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ³ ³ ³0³ ³ ³ ³ ³ ³ ³ ³ ³0³ ³0³ ³1³ º
|
||
º ³M³F³ ³T³ PL³F³F³F³F³F³F³ ³F³ ³F³ ³Fº
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÑÏÑÏÍÏÑÏÍØÍÏÑÏÑÏÑÏÑÏÑÏÑÏÍÏÑÏÍÏÑÏÍÏѼ
|
||
³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³
|
||
VIRTUAL 8086 MODEÄÄÄXÄÄÄÄÄÄÄÄÄÄÙ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³
|
||
RESUME FLAGÄÄÄXÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³
|
||
NESTED TASK FLAGÄÄÄXÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³
|
||
I/O PRIVILEGE LEVELÄÄÄXÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ ³ ³ ³ ³ ³ ³ ³ ³
|
||
OVERFLOWÄÄÄSÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ ³ ³ ³ ³ ³ ³ ³
|
||
DIRECTION FLAGÄÄÄCÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ ³ ³ ³ ³ ³ ³
|
||
INTERRUPT ENABLEÄÄÄXÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ ³ ³ ³ ³ ³
|
||
TRAP FLAGÄÄÄSÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ ³ ³ ³ ³
|
||
SIGN FLAGÄÄÄSÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ ³ ³ ³
|
||
ZERO FLAGÄÄÄSÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ ³ ³
|
||
AUXILIARY CARRYÄÄÄSÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ ³
|
||
PARITY FLAGÄÄÄSÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³
|
||
CARRY FLAGÄÄÄSÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
||
|
||
S = STATUS FLAG, C = CONTROL FLAG, X = SYSTEM FLAG
|
||
|
||
NOTE: 0 OR 1 INDICATES INTEL RESERVED. DO NOT DEFINE
|
||
|
||
|
||
2.3.4.1 Status Flags
|
||
|
||
The status flags of the EFLAGS register allow the results of one
|
||
instruction to influence later 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.
|
||
There are instructions to set, clear, and complement CF before execution of
|
||
an arithmetic instruction. Refer to Appendix C for definition of each
|
||
status flag.
|
||
|
||
|
||
2.3.4.2 Control Flag
|
||
|
||
The control flag DF of the EFLAGS register controls string instructions.
|
||
|
||
DF (Direction Flag, bit 10)
|
||
|
||
Setting DF causes string instructions to auto-decrement; that is, to
|
||
process strings from high addresses to low addresses. Clearing DF causes
|
||
string instructions to auto-increment, or to process strings from low
|
||
addresses to high addresses.
|
||
|
||
|
||
2.3.4.3 Instruction Pointer
|
||
|
||
The instruction pointer register (EIP) contains the offset address,
|
||
relative to the start of the current code segment, of the next sequential
|
||
instruction to be executed. The instruction pointer is not directly visible
|
||
to the programmer; it is controlled implicitly by control-transfer
|
||
instructions, interrupts, and exceptions.
|
||
|
||
As Figure 2-9 shows, the low-order 16 bits of EIP is named IP and can be
|
||
used by the processor as a unit. This feature is useful when executing
|
||
instructions designed for the 8086 and 80286 processors.
|
||
|
||
|
||
Figure 2-9. Instruction Pointer Register
|
||
|
||
16-BIT IP REGISTER
|
||
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
||
31 23 15 7 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º EIP (INSTRUCTION POINTER) º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
|
||
2.4 Instruction Format
|
||
|
||
The information encoded in an 80386 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.
|
||
|
||
80386 instructions are composed of various elements and have various
|
||
formats. The exact format of instructions is shown in Appendix B; the
|
||
elements of instructions are described below. Of these instruction 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. The elements of an instruction, in order
|
||
of occurrence are as follows:
|
||
|
||
þ Prefixes ÄÄ one or more bytes preceding an instruction that modify the
|
||
operation of the instruction. The following types of prefixes can be
|
||
used by applications programs:
|
||
|
||
1. Segment override ÄÄ explicitly specifies which segment register an
|
||
instruction should use, thereby overriding the default
|
||
segment-register selection used by the 80386 for that instruction.
|
||
|
||
2. Address size ÄÄ switches between 32-bit and 16-bit address
|
||
generation.
|
||
|
||
3. Operand size ÄÄ switches between 32-bit and 16-bit operands.
|
||
|
||
4. Repeat ÄÄ used with a string instruction to cause the instruction
|
||
to act on each element of the string.
|
||
|
||
þ Opcode ÄÄ specifies the operation performed by the instruction. Some
|
||
operations have several different opcodes, each specifying a different
|
||
variant of the operation.
|
||
|
||
þ Register specifier ÄÄ an instruction may specify one or two register
|
||
operands. Register specifiers may occur either in the same byte as the
|
||
opcode or in the same byte as the addressing-mode specifier.
|
||
|
||
þ Addressing-mode specifier ÄÄ when present, specifies whether an operand
|
||
is a register or memory location; if in memory, specifies whether a
|
||
displacement, a base register, an index register, and scaling are to be
|
||
used.
|
||
|
||
þ SIB (scale, index, base) byte ÄÄ when the addressing-mode specifier
|
||
indicates that an index register will be used to compute the address of
|
||
an operand, an SIB byte is included in the instruction to encode the
|
||
base register, the index register, and a scaling factor.
|
||
|
||
þ Displacement ÄÄ when the addressing-mode specifier indicates that a
|
||
displacement will be used to compute the address of an operand, the
|
||
displacement is encoded in the instruction. A displacement is a signed
|
||
integer of 32, 16, or eight bits. The eight-bit form is used in the
|
||
common case when the displacement is sufficiently small. The processor
|
||
extends an eight-bit displacement to 16 or 32 bits, taking into
|
||
account the sign.
|
||
|
||
þ Immediate operand ÄÄ when present, directly provides the value of an
|
||
operand of the instruction. Immediate operands may be 8, 16, or 32 bits
|
||
wide. In cases where an eight-bit immediate operand is combined in some
|
||
way with a 16- or 32-bit operand, the processor automatically extends
|
||
the size of the eight-bit operand, taking into account the sign.
|
||
|
||
|
||
2.5 Operand Selection
|
||
|
||
An instruction can act on zero or more operands, which are the data
|
||
manipulated by the instruction. An example of a zero-operand instruction is
|
||
NOP (no operation). An operand can be in any of these locations:
|
||
|
||
þ In the instruction itself (an immediate operand)
|
||
|
||
þ In a register (EAX, EBX, ECX, EDX, ESI, EDI, ESP, or EBP in the case
|
||
of 32-bit operands; 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 segment registers; or the EFLAGS register for flag
|
||
operations)
|
||
|
||
þ In memory
|
||
|
||
þ At 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.
|
||
Register operands are available in the CPU. Immediate operands are also
|
||
available in the CPU, because they are prefetched as part of the
|
||
instruction.
|
||
|
||
Of the instructions that have operands, some specify operands implicitly;
|
||
others specify operands explicitly; still others use a combination of
|
||
implicit and explicit specification; for example:
|
||
|
||
Implicit operand: AAM
|
||
|
||
By definition, AAM (ASCII adjust for multiplication) operates on the
|
||
contents of the AX register.
|
||
|
||
Explicit operand: XCHG EAX, EBX
|
||
|
||
The operands to be exchanged are encoded in the instruction after the
|
||
opcode.
|
||
|
||
Implicit and explicit operands: PUSH COUNTER
|
||
|
||
The memory variable COUNTER (the explicit operand) is copied to the top of
|
||
the stack (the implicit operand).
|
||
|
||
Note that most instructions have implicit operands. All arithmetic
|
||
instructions, for example, update the EFLAGS register.
|
||
|
||
An 80386 instruction can explicitly reference one or two operands.
|
||
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 unaffected by the
|
||
operation) and the destination operand (the one overwritten by the result).
|
||
|
||
For most instructions, one of the two explicitly specified operandsÄÄeither
|
||
the source or the destinationÄÄcan be either in a register or in memory.
|
||
The other operand must be in a register or be an immediate source operand.
|
||
Thus, the explicit two-operand instructions of the 80386 permit operations
|
||
of the following kinds:
|
||
|
||
þ Register-to-register
|
||
þ Register-to-memory
|
||
þ Memory-to-register
|
||
þ Immediate-to-register
|
||
þ Immediate-to-memory
|
||
|
||
Certain string instructions and stack manipulation instructions, however,
|
||
transfer data from memory to memory. Both operands of some string
|
||
instructions are in memory and are implicitly specified. Push and pop stack
|
||
operations allow transfer between memory operands and the memory-based
|
||
stack.
|
||
|
||
|
||
2.5.1 Immediate Operands
|
||
|
||
Certain instructions use data from the instruction itself as one (and
|
||
sometimes two) of the operands. Such an operand is called an immediate
|
||
operand. The operand may be 32-, 16-, or 8-bits long. For example:
|
||
|
||
SHR PATTERN, 2
|
||
|
||
One byte of the instruction holds the value 2, the number of bits by which
|
||
to shift the variable PATTERN.
|
||
|
||
TEST PATTERN, 0FFFF00FFH
|
||
|
||
A doubleword of the instruction holds the mask that is used to test the
|
||
variable PATTERN.
|
||
|
||
|
||
2.5.2 Register Operands
|
||
|
||
Operands may be located in one of the 32-bit general registers (EAX, EBX,
|
||
ECX, EDX, ESI, EDI, ESP, or EBP), in one of the 16-bit general 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).
|
||
|
||
The 80386 has instructions for referencing the segment registers (CS, DS,
|
||
ES, SS, FS, GS). These instructions are used by applications programs only
|
||
if systems designers have chosen a segmented memory model.
|
||
|
||
The 80386 also has instructions for referring to the flag register. The
|
||
flags may be stored on the stack and restored from the stack. Certain
|
||
instructions change the commonly modified flags directly in the EFLAGS
|
||
register. Other flags that are seldom modified can be modified indirectly
|
||
via the flags image in the stack.
|
||
|
||
|
||
2.5.3 Memory Operands
|
||
|
||
Data-manipulation instructions that address operands in memory must specify
|
||
(either directly or indirectly) the segment that contains the operand and
|
||
the offset of the operand within the segment. However, for speed and compact
|
||
instruction encoding, segment selectors are stored in the high speed segment
|
||
registers. Therefore, data-manipulation instructions need to specify only
|
||
the desired segment register and an offset in order to address a memory
|
||
operand.
|
||
|
||
An 80386 data-manipulation instruction that accesses memory uses one of the
|
||
following methods for specifying the offset of a memory operand within its
|
||
segment:
|
||
|
||
1. Most data-manipulation instructions that access memory contain a byte
|
||
that explicitly specifies the addressing method for the operand. A
|
||
byte, known as the modR/M byte, follows the opcode and specifies
|
||
whether the operand is in a register or in memory. If the operand is
|
||
in memory, the address is computed from a segment register and any of
|
||
the following values: a base register, an index register, a scaling
|
||
factor, a displacement. When an index register is used, the modR/M
|
||
byte is also followed by another byte that identifies the index
|
||
register and scaling factor. This addressing method is the
|
||
mostflexible.
|
||
|
||
2. A few data-manipulation instructions implicitly use specialized
|
||
addressing methods:
|
||
|
||
þ For a few short forms of MOV that implicitly use the EAX register,
|
||
the offset of the operand is coded as a doubleword in the
|
||
instruction. No base register, index register, or scaling factor
|
||
are used.
|
||
|
||
þ String operations implicitly address memory via DS:ESI, (MOVS,
|
||
CMPS, OUTS, LODS, SCAS) or via ES:EDI (MOVS, CMPS, INS, STOS).
|
||
|
||
þ Stack operations implicitly address operands via SS:ESP
|
||
registers; e.g., PUSH, POP, PUSHA, PUSHAD, POPA, POPAD, PUSHF,
|
||
PUSHFD, POPF, POPFD, CALL, RET, IRET, IRETD, exceptions, and
|
||
interrupts.
|
||
|
||
|
||
2.5.3.1 Segment Selection
|
||
|
||
Data-manipulation instructions need not explicitly specify which segment
|
||
register is used. For all of these instructions, specification of a segment
|
||
register is optional. For all memory accesses, if a segment is not
|
||
explicitly specified by the instruction, the processor automatically chooses
|
||
a segment register according to the rules of Table 2-1. (If systems
|
||
designers have chosen a flat model of memory organization, the segment
|
||
registers and the rules that the processor uses in choosing them are not
|
||
apparent to applications programs.)
|
||
|
||
There is a close connection between the kind of memory reference and the
|
||
segment in which that operand resides. As a rule, a memory reference implies
|
||
the current data segment (i.e., the implicit segment selector is in DS).
|
||
However, ESP and EBP are used to access items on the stack; therefore, when
|
||
the ESP or EBP register is used as a base register, the current stack
|
||
segment is implied (i.e., SS contains the selector).
|
||
|
||
Special instruction prefix elements may be used to override the default
|
||
segment selection. Segment-override prefixes allow an explicit segment
|
||
selection. The 80386 has a segment-override prefix for each of the segment
|
||
registers. Only in the following special cases is there an implied segment
|
||
selection that a segment prefix cannot override:
|
||
|
||
þ The use of ES for destination strings in string instructions.
|
||
þ The use of SS in stack instructions.
|
||
þ The use of CS for instruction fetches.
|
||
|
||
|
||
Table 2-1. Default Segment Register Selection Rules
|
||
|
||
Memory Reference Needed Segment Implicit Segment Selection Rule
|
||
Register
|
||
Used
|
||
|
||
Instructions Code (CS) Automatic with instruction prefetch
|
||
Stack Stack (SS) All stack pushes and pops. Any
|
||
memory reference that uses ESP or
|
||
EBP as a base register.
|
||
Local Data Data (DS) All data references except when
|
||
relative to stack or string
|
||
destination.
|
||
Destination Strings Extra (ES) Destination of string instructions.
|
||
|
||
|
||
2.5.3.2 Effective-Address Computation
|
||
|
||
The modR/M byte provides the most flexible of the addressing methods, and
|
||
instructions that require a modR/M byte as the second byte of the
|
||
instruction are the most common in the 80386 instruction set. For memory
|
||
operands defined by modR/M, the offset within the desired segment is
|
||
calculated by taking the sum of up to three components:
|
||
|
||
þ A displacement element in the instruction.
|
||
|
||
þ A base register.
|
||
|
||
þ An index register. The index register may be automatically multiplied
|
||
by a scaling factor of 2, 4, or 8.
|
||
|
||
The offset that results from adding these components is called an effective
|
||
address. Each of these components of an effective address may have either a
|
||
positive or negative value. If the sum of all the components exceeds 2^(32),
|
||
the effective address is truncated to 32 bits.Figure 2-10 illustrates the
|
||
full set of possibilities for modR/M addressing.
|
||
|
||
The displacement component, because it is encoded in the instruction, is
|
||
useful for fixed aspects of addressing; for example:
|
||
|
||
þ Location of simple scalar operands.
|
||
þ Beginning of a statically allocated array.
|
||
þ Offset of an item within a record.
|
||
|
||
The base and index components have similar functions. Both utilize the same
|
||
set of general registers. Both can be used for aspects of addressing that
|
||
are determined dynamically; for example:
|
||
|
||
þ Location of procedure parameters and local variables in stack.
|
||
|
||
þ The beginning of one record among several occurrences of the same
|
||
record type or in an array of records.
|
||
|
||
þ The beginning of one dimension of multiple dimension array.
|
||
|
||
þ The beginning of a dynamically allocated array.
|
||
|
||
The uses of general registers as base or index components differ in the
|
||
following respects:
|
||
|
||
þ ESP cannot be used as an index register.
|
||
|
||
þ When ESP or EBP is used as the base register, the default segment is
|
||
the one selected by SS. In all other cases the default segment is DS.
|
||
|
||
The scaling factor permits efficient indexing into an array in the common
|
||
cases when array elements are 2, 4, or 8 bytes wide. The shifting of the
|
||
index register is done by the processor at the time the address is evaluated
|
||
with no performance loss. This eliminates the need for a separate shift or
|
||
multiply instruction.
|
||
|
||
The base, index, and displacement components may be used in any
|
||
combination; any of these components may be null. A scale factor can be used
|
||
only when an index is also used. Each possible combination is useful for
|
||
data structures commonly used by programmers in high-level languages and
|
||
assembly languages. Following are possible uses for some of the various
|
||
combinations of address components.
|
||
|
||
DISPLACEMENT
|
||
|
||
The displacement alone indicates the offset of the operand. This
|
||
combination is used to directly address a statically allocated scalar
|
||
operand. An 8-bit, 16-bit, or 32-bit displacement can be used.
|
||
|
||
BASE
|
||
|
||
The offset of the operand is specified indirectly in one of the general
|
||
registers, as for "based" variables.
|
||
|
||
BASE + DISPLACEMENT
|
||
|
||
A register and a displacement can be used together for two distinct
|
||
purposes:
|
||
|
||
1. Index into static array when element size is not 2, 4, or 8 bytes.
|
||
The displacement component encodes the offset of the beginning of
|
||
the array. The register holds the results of a calculation to
|
||
determine the offset of a specific element within the array.
|
||
|
||
2. Access item of a record. The displacement component locates an
|
||
item within record. The base register selects one of several
|
||
occurrences of record, thereby providing a compact encoding for
|
||
this common function.
|
||
|
||
An important special case of this combination, is to access parameters
|
||
in the procedure activation record in the stack. In this case, EBP is
|
||
the best choice for the base register, because when EBP is used as a
|
||
base register, the processor automatically uses the stack segment
|
||
register (SS) to locate the operand, thereby providing a compact
|
||
encoding for this common function.
|
||
|
||
(INDEX * SCALE) + DISPLACEMENT
|
||
|
||
This combination provides efficient indexing into a static array when
|
||
the element size is 2, 4, or 8 bytes. The displacement addresses the
|
||
beginning of the array, the index register holds the subscript of the
|
||
desired array element, and the processor automatically converts the
|
||
subscript into an index by applying the scaling factor.
|
||
|
||
BASE + INDEX + DISPLACEMENT
|
||
|
||
Two registers used together support either a two-dimensional array (the
|
||
displacement determining the beginning of the array) or one of several
|
||
instances of an array of records (the displacement indicating an item
|
||
in the record).
|
||
|
||
BASE + (INDEX * SCALE) + DISPLACEMENT
|
||
|
||
This combination provides efficient indexing of a two-dimensional array
|
||
when the elements of the array are 2, 4, or 8 bytes wide.
|
||
|
||
|
||
Figure 2-10. Effective Address Computation
|
||
|
||
SEGMENT + BASE + (INDEX * SCALE) + DISPLACEMENT
|
||
|
||
Ú ¿
|
||
³ --- ³ Ú ¿ Ú ¿
|
||
Ú ¿ ³ EAX ³ ³ EAX ³ ³ 1 ³
|
||
³ CS ³ ³ ECX ³ ³ ECX ³ ³ ³ Ú ¿
|
||
³ SS ³ ³ EDX ³ ³ EDX ³ ³ 2 ³ ³ NO DISPLACEMENT ³
|
||
Ä´ DS ÃÄ + Ä´ EBX ÃÄ + Ä´ EBX ÃÄ * Ä´ ÃÄ + Ä´ 8-BIT DISPLACEMENT ÃÄ
|
||
³ ES ³ ³ ESP ³ ³ --- ³ ³ 4 ³ ³ 32-BIT DISPLACEMENT ³
|
||
³ FS ³ ³ EBP ³ ³ EBP ³ ³ ³ À Ù
|
||
³ GS ³ ³ ESI ³ ³ ESI ³ ³ 6 ³
|
||
À Ù ³ EDI ³ ³ EDI ³ À Ù
|
||
À Ù À Ù
|
||
|
||
|
||
2.6 Interrupts and Exceptions
|
||
|
||
The 80386 has two mechanisms for interrupting program execution:
|
||
|
||
1. Exceptions are synchronous events that are the responses of the CPU
|
||
to certain conditions detected during the execution of an instruction.
|
||
|
||
2. Interrupts are asynchronous events typically triggered by external
|
||
devices needing attention.
|
||
|
||
Interrupts and exceptions are alike in that both cause the processor to
|
||
temporarily suspend its present program execution in order to execute a
|
||
program of higher priority. The major distinction between these two kinds of
|
||
interrupts is their origin. An exception is always reproducible by
|
||
re-executing with the program and data that caused the exception, whereas an
|
||
interrupt is generally independent of the currently executing program.
|
||
|
||
Application programmers are not normally concerned with servicing
|
||
interrupts. More information on interrupts for systems programmers may be
|
||
found in Chapter 9. Certain exceptions, however, are of interest to
|
||
applications programmers, and many operating systems give applications
|
||
programs the opportunity to service these exceptions. However, the operating
|
||
system itself defines the interface between the applications programs and
|
||
the exception mechanism of the 80386.
|
||
|
||
Table 2-2 highlights the exceptions that may be of interest to applications
|
||
programmers.
|
||
|
||
þ A divide error exception results when the instruction DIV or IDIV is
|
||
executed with a zero denominator or when the quotient is too large for
|
||
the destination operand. (Refer to Chapter 3 for a discussion of DIV
|
||
and IDIV.)
|
||
|
||
þ The debug exception may be reflected back to an applications program
|
||
if it results from the trap flag (TF).
|
||
|
||
þ A breakpoint exception results when the instruction INT 3 is executed.
|
||
This instruction is used by some debuggers to stop program execution at
|
||
specific points.
|
||
|
||
þ An overflow exception results when the INTO instruction is executed
|
||
and the OF (overflow) flag is set (after an arithmetic operation that
|
||
set the OF flag). (Refer to Chapter 3 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. (Refer to Chapter 3 for a discussion of the BOUND instruction.)
|
||
|
||
þ Invalid opcodes may be used by some applications to extend the
|
||
instruction set. In such a case, the invalid opcode exception presents
|
||
an opportunity to emulate the opcode.
|
||
|
||
þ The "coprocessor not available" exception occurs if the program
|
||
contains instructions for a coprocessor, but no coprocessor is present
|
||
in the system.
|
||
|
||
þ A coprocessor error is generated when a coprocessor detects an illegal
|
||
operation.
|
||
|
||
The instruction INT generates an interrupt whenever it is executed; the
|
||
processor treats this interrupt as an exception. The effects of this
|
||
interrupt (and the effects of all other exceptions) are determined by
|
||
exception handler routines provided by the application program or as part of
|
||
the systems software (provided by systems programmers). The INT instruction
|
||
itself is discussed in Chapter 3. Refer to Chapter 9 for a more complete
|
||
description of exceptions.
|
||
|
||
|
||
Table 2-2. 80386 Reserved Exceptions and Interrupts
|
||
|
||
Vector Number Description
|
||
|
||
0 Divide Error
|
||
1 Debug Exceptions
|
||
2 NMI Interrupt
|
||
3 Breakpoint
|
||
4 INTO Detected Overflow
|
||
5 BOUND Range Exceeded
|
||
6 Invalid Opcode
|
||
7 Coprocessor Not Available
|
||
8 Double Exception
|
||
9 Coprocessor Segment Overrun
|
||
10 Invalid Task State Segment
|
||
11 Segment Not Present
|
||
12 Stack Fault
|
||
13 General Protection
|
||
14 Page Fault
|
||
15 (reserved)
|
||
16 Coprocessor Error
|
||
17-32 (reserved)
|
||
|
||
|
||
Chapter 3 Applications Instruction Set
|
||
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
This chapter presents an overview of the instructions which programmers can
|
||
use to write application software for the 80386 executing in protected
|
||
virtual-address mode. The instructions are grouped by categories of related
|
||
functions.
|
||
|
||
The instructions not discussed in this chapter are those that are normally
|
||
used only by operating-system programmers. Part II describes the operation
|
||
of these instructions.
|
||
|
||
The descriptions in this chapter assume that the 80386 is operating in
|
||
protected mode with 32-bit addressing in effect; however, all instructions
|
||
discussed are also available when 16-bit addressing is in effect in
|
||
protected mode, real mode, or virtual 8086 mode. For any differences of
|
||
operation that exist in the various modes, refer to Chapter 13,
|
||
Chapter 14, or Chapter 15.
|
||
|
||
The instruction dictionary in Chapter 17 contains more detailed
|
||
descriptions of all instructions, including encoding, operation, timing,
|
||
effect on flags, and exceptions.
|
||
|
||
|
||
3.1 Data Movement Instructions
|
||
|
||
These instructions provide convenient methods for moving bytes, words, or
|
||
doublewords of data between memory and the registers of the base
|
||
architecture. They fall into the following classes:
|
||
|
||
1. General-purpose data movement instructions.
|
||
2. Stack manipulation instructions.
|
||
3. Type-conversion instructions.
|
||
|
||
|
||
3.1.1 General-Purpose Data Movement Instructions
|
||
|
||
MOV (Move) transfers a byte, word, or doubleword from the source operand to
|
||
the destination operand. The MOV instruction is useful for transferring data
|
||
along any of these paths
|
||
There are also variants of MOV that operate on segment registers. These
|
||
are covered in a later section of this chapter.:
|
||
|
||
þ To a register from memory
|
||
þ To memory from a register
|
||
þ Between general registers
|
||
þ Immediate data to a register
|
||
þ Immediate data to a memory
|
||
|
||
The MOV instruction cannot move from memory to memory or from segment
|
||
register to segment register are not allowed. Memory-to-memory moves can be
|
||
performed, however, by the string move instruction MOVS.
|
||
|
||
XCHG (Exchange) swaps the contents of two operands. This instruction takes
|
||
the place of three MOV instructions. It does not require a temporary
|
||
location to save the contents of one operand while load the other is being
|
||
loaded. XCHG is especially useful for implementing semaphores or similar
|
||
data structures for process synchronization.
|
||
|
||
The XCHG instruction can swap two byte operands, two word operands, or two
|
||
doubleword operands. 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. (Refer
|
||
to Chapter 11 for more information on the bus lock.)
|
||
|
||
|
||
3.1.2 Stack Manipulation Instructions
|
||
|
||
PUSH (Push) decrements the stack pointer (ESP), then transfers the source
|
||
operand to the top of stack indicated by ESP (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, and
|
||
register operands (including segment registers).
|
||
|
||
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. The processor
|
||
pushes the general registers on the stack in the following order: EAX, ECX,
|
||
EDX, EBX, the initial value of ESP before EAX was pushed, EBP, ESI, and
|
||
EDI. PUSHA is complemented by the POPA instruction.
|
||
|
||
POP (Pop) transfers the word or doubleword at the current top of stack
|
||
(indicated by ESP) to the destination operand, and then increments ESP to
|
||
point to the new top of stack. See Figure 3-3. POP moves information from
|
||
the stack to a general register, or to memory
|
||
There are also a variant of POP that operates on segment registers. This
|
||
is covered in a later section of this chapter..
|
||
|
||
POPA (Pop All Registers) restores the registers saved on the stack by
|
||
PUSHA, except that it ignores the saved value of ESP. See Figure 3-4.
|
||
|
||
|
||
Figure 3-1. PUSH
|
||
|
||
D O BEFORE PUSH AFTER PUSH
|
||
I F 31 0 31 0
|
||
R º º º º
|
||
E E ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
C X º±±±±±±±±±±±±±±±º º±±±±±±±±±±±±±±±º
|
||
T P ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
I A º±±±±±±±±±±±±±±±º º±±±±±±±±±±±±±±±º
|
||
O N ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ÄÄESP ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
N S º º º OPERAND º
|
||
I ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ÄÄESP
|
||
³ O º º º º
|
||
³ N ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
³ º º º º
|
||
ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
º º º º
|
||
|
||
|
||
|
||
Figure 3-2. PUSHA
|
||
|
||
BEFORE PUSHA AFTER PUSHA
|
||
31 0 31 0
|
||
D O º º º º
|
||
I F ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
R º±±±±±±±±±±±±±±±º º±±±±±±±±±±±±±±±º
|
||
E E ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
C X º±±±±±±±±±±±±±±±º º±±±±±±±±±±±±±±±º
|
||
T P ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ÄÄESP ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
I A º º º EAX º
|
||
O N ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
N S º º º ECX º
|
||
I ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
³ O º º º EDX º
|
||
³ N ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
³ º º º EBX º
|
||
ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
º º º OLD ESP º
|
||
ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
º º º EBP º
|
||
ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
º º º ESI º
|
||
ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
º º º EDI º
|
||
ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ÄÄESP
|
||
º º º º
|
||
ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
º º º º
|
||
|
||
|
||
|
||
3.1.3 Type Conversion Instructions
|
||
|
||
The type conversion instructions convert bytes into words, words into
|
||
doublewords, and doublewords into 64-bit items (quad-words). These
|
||
instructions are especially useful for converting signed integers, because
|
||
they automatically fill the extra bits of the larger item with the value of
|
||
the sign bit of the smaller item. This kind of conversion, illustrated by
|
||
Figure 3-5, is called sign extension.
|
||
|
||
There are two classes of type conversion instructions:
|
||
|
||
1. The forms CWD, CDQ, CBW, and CWDE which operate only on data in the
|
||
EAX register.
|
||
|
||
2. The forms MOVSX and MOVZX, which permit one operand to be in any
|
||
general register while permitting the other operand to be in memory or
|
||
in a register.
|
||
|
||
CWD (Convert Word to Doubleword) and CDQ (Convert Doubleword to Quad-Word)
|
||
double the size of the source operand. CWD extends the sign of the
|
||
word in register AX throughout register DX. CDQ extends the sign of the
|
||
doubleword in EAX throughout EDX. CWD can be used to produce a doubleword
|
||
dividend from a word before a word division, and CDQ can be used to produce
|
||
a quad-word dividend from a doubleword before doubleword division.
|
||
|
||
CBW (Convert Byte to Word) extends the sign of the byte in register AL
|
||
throughout AX.
|
||
|
||
CWDE (Convert Word to Doubleword Extended) extends the sign of the word in
|
||
register AX throughout EAX.
|
||
|
||
MOVSX (Move with Sign Extension) sign-extends an 8-bit value to a 16-bit
|
||
value and a 8- or 16-bit value to 32-bit value.
|
||
|
||
MOVZX (Move with Zero Extension) extends an 8-bit value to a 16-bit value
|
||
and an 8- or 16-bit value to 32-bit value by inserting high-order zeros.
|
||
|
||
|
||
Figure 3-3. POP
|
||
|
||
D O BEFORE POP AFTER POP
|
||
I F 31 0 31 0
|
||
R º º º º
|
||
E E ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
C X º±±±±±±±±±±±±±±±º º±±±±±±±±±±±±±±±º
|
||
T P ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
I A º±±±±±±±±±±±±±±±º º±±±±±±±±±±±±±±±º
|
||
O N ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ÄÄESP
|
||
N S º OPERAND º º º
|
||
I ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ÄÄESP ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
³ O º º º º
|
||
³ N ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
³ º º º º
|
||
ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
º º º º
|
||
|
||
|
||
|
||
Figure 3-4. POPA
|
||
|
||
BEFORE POPA AFTER POPA
|
||
31 0 31 0
|
||
D O º º º º
|
||
I F ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
R º±±±±±±±±±±±±±±±º º±±±±±±±±±±±±±±±º
|
||
E E ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
C X º±±±±±±±±±±±±±±±º º±±±±±±±±±±±±±±±º
|
||
T P ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ÄÄESP
|
||
I A º EAX º º º
|
||
O N ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
N S º ECX º º º
|
||
I ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
³ O º EDX º º º
|
||
³ N ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
³ º EBX º º º
|
||
ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
º ESP º º º
|
||
ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
º EPB º º º
|
||
ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
º ESI º º º
|
||
ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
º EDI º º º
|
||
ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ÄÄESP ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
º º º º
|
||
ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
º º º º
|
||
|
||
|
||
|
||
Figure 3-5. Sign Extension
|
||
|
||
15 7 0
|
||
ÉÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
BEFORE SIGN EXTENSIONÄÄÄÄÄÄÄÄĺSº N N N N N N N N N N N N N N N º
|
||
ÈÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
AFTER SIGN EXTENSIONÄÄÄÄÄÄ¿
|
||
³
|
||
31 23 15 7 0
|
||
ÉÍËÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
ºSºS S S S S S S S S S S S S S S S N N N N N N N N N N N N N N Nº
|
||
ÈÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
|
||
3.2 Binary Arithmetic Instructions
|
||
|
||
The arithmetic instructions of the 80386 processor simplify the
|
||
manipulation of numeric data that is encoded in binary. Operations include
|
||
the standard add, subtract, multiply, and divide as well as increment,
|
||
decrement, compare, and change sign. Both signed and unsigned binary
|
||
integers are supported. The binary arithmetic instructions may also be used
|
||
as one step in the process of performing arithmetic on decimal integers.
|
||
|
||
Many of the arithmetic instructions operate on both signed and unsigned
|
||
integers. These instructions update the flags ZF, CF, SF, and OF in such a
|
||
manner that subsequent instructions can interpret the results of the
|
||
arithmetic as either signed or unsigned. CF contains information relevant to
|
||
unsigned integers; SF and OF contain information relevant to signed
|
||
integers. ZF is relevant to both signed and unsigned integers; ZF is set
|
||
when all bits of the result are zero.
|
||
|
||
If the integer is unsigned, CF may be tested after one of these arithmetic
|
||
operations to determine whether the operation required a carry or borrow of
|
||
a one-bit in the high-order position of the destination operand. CF is set
|
||
if a one-bit was carried out of the high-order position (addition
|
||
instructions ADD, ADC, AAA, and DAA) or if a one-bit was carried (i.e.
|
||
borrowed) into the high-order bit (subtraction instructions SUB, SBB, AAS,
|
||
DAS, CMP, and NEG).
|
||
|
||
If the integer is signed, both SF and OF should be tested. SF always has
|
||
the same value as the sign bit of the result. The most significant bit (MSB)
|
||
of a signed integer is the bit next to the signÄÄbit 6 of a byte, bit 14 of
|
||
a word, or bit 30 of a doubleword. OF is set in either of these cases:
|
||
|
||
þ A one-bit was carried out of the MSB into the sign bit but no one bit
|
||
was carried out of the sign bit (addition instructions ADD, ADC, INC,
|
||
AAA, and DAA). In other words, the result was greater than the greatest
|
||
positive number that could be contained in the destination operand.
|
||
|
||
þ A one-bit was carried from the sign bit into the MSB but no one bit
|
||
was carried into the sign bit (subtraction instructions SUB, SBB, DEC,
|
||
AAS, DAS, CMP, and NEG). In other words, the result was smaller that
|
||
the smallest negative number that could be contained in the destination
|
||
operand.
|
||
|
||
These status flags are tested by executing one of the two families of
|
||
conditional instructions: Jcc (jump on condition cc) or SETcc (byte set on
|
||
condition).
|
||
|
||
|
||
3.2.1 Addition and Subtraction Instructions
|
||
|
||
ADD (Add Integers) replaces the destination operand with the sum of the
|
||
source and destination operands. Sets CF if overflow.
|
||
|
||
ADC (Add Integers with Carry) sums the operands, adds one if CF is set, and
|
||
replaces the destination operand with the result. If CF is cleared, ADC
|
||
performs the same operation as the ADD instruction. An ADD followed by
|
||
multiple ADC instructions can be used to add numbers longer than 32 bits.
|
||
|
||
INC (Increment) adds one to the destination operand. INC does not affect
|
||
CF. Use ADD with an immediate value of 1 if an increment that updates carry
|
||
(CF) is needed.
|
||
|
||
SUB (Subtract Integers) subtracts the source operand from the destination
|
||
operand and replaces the destination operand with the result. If a borrow is
|
||
required, the CF is set. The operands may be signed or unsigned bytes,
|
||
words, or doublewords.
|
||
|
||
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. If CF is cleared, SBB performs the same operation as
|
||
SUB. SUB followed by multiple SBB instructions may be used to subtract
|
||
numbers longer than 32 bits. If CF is cleared, SBB performs the same
|
||
operation as SUB.
|
||
|
||
DEC (Decrement) subtracts 1 from the destination operand. DEC does not
|
||
update CF. Use SUB with an immediate value of 1 to perform a decrement that
|
||
affects carry.
|
||
|
||
|
||
3.2.2 Comparison and Sign Change Instruction
|
||
|
||
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 Jcc or SETcc instruction can test the
|
||
appropriate flags.
|
||
|
||
NEG (Negate) subtracts a signed integer operand from zero. The effect of
|
||
NEG is to reverse the sign of the operand from positive to negative or from
|
||
negative to positive.
|
||
|
||
|
||
3.2.3 Multiplication Instructions
|
||
|
||
The 80386 has separate multiply instructions for unsigned and signed
|
||
operands. MUL operates on unsigned numbers, while IMUL operates on signed
|
||
integers as well as unsigned.
|
||
|
||
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. If the
|
||
source operand is a doubleword, the processor multiplies it by the contents
|
||
of EAX and returns the 64-bit result in EDX and EAX. MUL sets CF and OF
|
||
when the upper half of the result is nonzero; otherwise, they are cleared.
|
||
|
||
IMUL (Signed Integer Multiply) performs a signed multiplication operation.
|
||
IMUL has three variations:
|
||
|
||
1. A one-operand form. The operand may be a byte, word, or doubleword
|
||
located in memory or in a general register. This instruction uses EAX
|
||
and EDX as implicit operands in the same way as the MUL instruction.
|
||
|
||
2. A two-operand form. One of the source operands may be in any general
|
||
register while the other may be either in memory or in a general
|
||
register. The product replaces the general-register operand.
|
||
|
||
3. A three-operand form; two are source and one is the destination
|
||
operand. One of the source operands is an immediate value stored in
|
||
the instruction; the second may be in memory or in any general
|
||
register. The product may be stored in any general register. The
|
||
immediate operand is treated as signed. If the immediate operand is a
|
||
byte, the processor automatically sign-extends it to the size of the
|
||
second operand before performing the multiplication.
|
||
|
||
The three forms are similar in most respects:
|
||
|
||
þ The length of the product is calculated to twice the length of the
|
||
operands.
|
||
|
||
þ The CF and OF flags are set when significant bits are carried into the
|
||
high-order half of the result. CF and OF are cleared when the
|
||
high-order half of the result is the sign-extension of the low-order
|
||
half.
|
||
|
||
However, forms 2 and 3 differ in that the product is truncated to the
|
||
length of the operands before it is stored in the destination register.
|
||
Because of this truncation, OF should be tested to ensure that no
|
||
significant bits are lost. (For ways to test OF, refer to the INTO and PUSHF
|
||
instructions.)
|
||
|
||
Forms 2 and 3 of IMUL may also be used with unsigned operands because,
|
||
whether the operands are signed or unsigned, the low-order half of the
|
||
product is the same.
|
||
|
||
|
||
3.2.4 Division Instructions
|
||
|
||
The 80386 has separate division instructions for unsigned and signed
|
||
operands. DIV operates on unsigned numbers, while IDIV operates on signed
|
||
integers as well as unsigned. In either case, an exception (interrupt zero)
|
||
occurs if the divisor is zero or if the quotient is too large for AL, AX, or
|
||
EAX.
|
||
|
||
DIV (Unsigned Integer Divide) performs an unsigned division of the
|
||
accumulator by the source operand. The dividend (the accumulator) is twice
|
||
the size of the divisor (the source operand); the quotient and remainder
|
||
have the same size as the divisor, as the following table shows.
|
||
|
||
Size of Source Operand
|
||
(divisor) Dividend Quotient Remainder
|
||
|
||
Byte AX AL AH
|
||
Word DX:AX AX DX
|
||
Doubleword EDX:EAX EAX EDX
|
||
|
||
Non-integral quotients are truncated to integers toward 0. The remainder is
|
||
always less than the divisor. For unsigned byte division, the largest
|
||
quotient is 255. For unsigned word division, the largest quotient is 65,535.
|
||
For unsigned doubleword division the largest quotient is 2^(32) -1.
|
||
|
||
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.
|
||
For signed doubleword division the maximum positive quotient is 2^(31) -1,
|
||
the minimum negative quotient is -2^(31). Non-integral results are truncated
|
||
towards 0. The remainder always has the same sign as the dividend and is
|
||
less than the divisor in magnitude.
|
||
|
||
|
||
3.3 Decimal Arithmetic Instructions
|
||
|
||
Decimal arithmetic is performed by combining the binary arithmetic
|
||
instructions (already discussed in the prior section) with the decimal
|
||
arithmetic instructions. The decimal arithmetic instructions are used in one
|
||
of the following ways:
|
||
|
||
þ To adjust the results of a previous binary arithmetic operation to
|
||
produce a valid packed or unpacked decimal result.
|
||
|
||
þ To adjust the inputs to a subsequent binary arithmetic operation so
|
||
that the operation will produce a valid packed or unpacked decimal
|
||
result.
|
||
|
||
These instructions operate only on the AL or AH registers. Most utilize the
|
||
AF flag.
|
||
|
||
|
||
3.3.1 Packed BCD Adjustment Instructions
|
||
|
||
DAA (Decimal Adjust after Addition) adjusts 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 half-byte) to obtain a
|
||
pair of valid packed decimal digits as results. The carry flag is set if
|
||
carry was needed.
|
||
|
||
DAS (Decimal Adjust after Subtraction) adjusts 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 half-
|
||
byte) from another to obtain a pair of valid packed decimal digits as
|
||
results. The carry flag is set if a borrow was needed.
|
||
|
||
|
||
3.3.2 Unpacked BCD Adjustment Instructions
|
||
|
||
AAA (ASCII Adjust after 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
|
||
is set and AH is incremented if a carry is necessary.
|
||
|
||
AAS (ASCII Adjust after 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 is set and AH decremented if a borrow is necessary.
|
||
|
||
AAM (ASCII Adjust after 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 is left in AH, the low order digit in AL.
|
||
|
||
AAD (ASCII Adjust before 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 adjusts the value and places the result in AL. AH will contain
|
||
zero.
|
||
|
||
|
||
3.4 Logical Instructions
|
||
|
||
The group of logical instructions includes:
|
||
|
||
þ The Boolean operation instructions
|
||
þ Bit test and modify instructions
|
||
þ Bit scan instructions
|
||
þ Rotate and shift instructions
|
||
þ Byte set on condition
|
||
|
||
|
||
3.4.1 Boolean Operation Instructions
|
||
|
||
The logical operations are AND, OR, XOR, and NOT.
|
||
|
||
NOT (Not) inverts the bits in the specified operand to form a one's
|
||
complement of the operand. The NOT instruction is a unary operation that
|
||
uses a single operand in a register or memory. NOT has no effect on the
|
||
flags.
|
||
|
||
The AND, OR, and XOR instructions perform the standard logical operations
|
||
"and", "(inclusive) or", and "exclusive or". These instructions can use the
|
||
following combinations of operands:
|
||
|
||
þ Two register operands
|
||
|
||
þ A general register operand with a memory operand
|
||
|
||
þ An immediate operand with either a general register operand or a
|
||
memory operand.
|
||
|
||
AND, OR, and XOR clear OF and CF, leave AF undefined, and update SF, ZF,
|
||
and PF.
|
||
|
||
|
||
3.4.2 Bit Test and Modify Instructions
|
||
|
||
This group of instructions operates on a single bit which can be in memory
|
||
or in a general register. The location of the bit is specified as an offset
|
||
from the low-order end of the operand. The value of the offset either may be
|
||
given by an immediate byte in the instruction or may be contained in a
|
||
general register.
|
||
|
||
These instructions first assign the value of the selected bit to CF, the
|
||
carry flag. Then a new value is assigned to the selected bit, as determined
|
||
by the operation. OF, SF, ZF, AF, PF are left in an undefined state. Table
|
||
3-1 defines these instructions.
|
||
|
||
|
||
Table 3-1. Bit Test and Modify Instructions
|
||
|
||
Instruction Effect on CF Effect on
|
||
Selected Bit
|
||
|
||
Bit (Bit Test) CF BIT (none)
|
||
BTS (Bit Test and Set) CF BIT BIT 1
|
||
BTR (Bit Test and Reset) CF BIT BIT 0
|
||
BTC (Bit Test and Complement) CF BIT BIT NOT(BIT)
|
||
|
||
|
||
3.4.3 Bit Scan Instructions
|
||
|
||
These instructions scan a word or doubleword for a one-bit and store the
|
||
index of the first set bit into a register. The bit string being scanned
|
||
may be either in a register or in memory. The ZF flag is set if the entire
|
||
word is zero (no set bits are found); ZF is cleared if a one-bit is found.
|
||
If no set bit is found, the value of the destination register is undefined.
|
||
|
||
BSF (Bit Scan Forward) scans from low-order to high-order (starting from
|
||
bit index zero).
|
||
|
||
BSR (Bit Scan Reverse) scans from high-order to low-order (starting from
|
||
bit index 15 of a word or index 31 of a doubleword).
|
||
|
||
|
||
3.4.4 Shift and Rotate Instructions
|
||
|
||
The shift and rotate instructions reposition the bits within the specified
|
||
operand.
|
||
|
||
These instructions fall into the following classes:
|
||
|
||
þ Shift instructions
|
||
þ Double shift instructions
|
||
þ Rotate instructions
|
||
|
||
|
||
3.4.4.1 Shift Instructions
|
||
|
||
The bits in bytes, words, and doublewords may be shifted arithmetically or
|
||
logically. Depending on the value of a specified count, bits can be shifted
|
||
up to 31 places.
|
||
|
||
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.
|
||
|
||
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.
|
||
|
||
The shift instructions provide a convenient way to accomplish division or
|
||
multiplication by binary power. Note however that division of signed numbers
|
||
by shifting right is not the same kind of division performed by the IDIV
|
||
instruction.
|
||
|
||
SAL (Shift Arithmetic Left) shifts the destination byte, word, or
|
||
doubleword 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 (low-order) side of the operand as
|
||
bits exit from the left (high-order) side. See Figure 3-6.
|
||
|
||
SHL (Shift Logical Left) is a synonym for SAL (refer to SAL).
|
||
|
||
SHR (Shift Logical Right) shifts the destination byte, word, or doubleword
|
||
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.
|
||
|
||
SAR (Shift Arithmetic Right) shifts the destination byte, word, or
|
||
doubleword 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
|
||
(high-order) side if the value is positive or by shifting by ones if the
|
||
value is negative. See Figure 3-8.
|
||
|
||
Even though this instruction can be used to divide integers by a power of
|
||
two, the type of division is not the same as that produced by the IDIV
|
||
instruction. The quotient of IDIV is rounded toward zero, whereas the
|
||
"quotient" of SAR is rounded toward negative infinity. This difference is
|
||
apparent only for negative numbers. For example, when IDIV is used to divide
|
||
-9 by 4, the result is -2 with a remainder of -1. If SAR is used to shift
|
||
-9 right by two bits, the result is -3. The "remainder" of this kind of
|
||
division is +3; however, the SAR instruction stores only the high-order bit
|
||
of the remainder (in CF).
|
||
|
||
The code sequence in Figure 3-9 produces the same result as IDIV for any M
|
||
= 2^(N), where 0 < N < 32. This sequence takes about 12 to 18 clocks,
|
||
depending on whether the jump is taken; if ECX contains M, the corresponding
|
||
IDIV ECX instruction will take about 43 clocks.
|
||
|
||
|
||
Figure 3-6. SAL and SHL
|
||
|
||
OF CF OPERAND
|
||
|
||
BEFORE SHL X X 10001000100010001000100010001111
|
||
OR SAL
|
||
|
||
AFTER SHL 1 1 ÄÄ 00010001000100010001000100011110 ÄÄ 0
|
||
OR SAL BY 1
|
||
|
||
AFTER SHL X 0 ÄÄ 00100010001000100011110000000000 ÄÄ 0
|
||
OR SAL BY 10
|
||
|
||
SHL (WHICH HAS THE SYNONYM SAL) SHIFTS 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. SHL SHIFTS IN ZEROS
|
||
TO FILL THE VACATED BIT LOCATIONS. THESE INSTRUCTIONS OPERATE ON BYTE,
|
||
WORD, AND DOUBLEWORD OPERANDS.
|
||
|
||
|
||
Figure 3-7. SHR
|
||
|
||
OPERAND CF
|
||
|
||
BEFORE SHR 10001000100010001000100010001111 X
|
||
|
||
AFTER SHR 0ÄÄÄÄ01000100010001000100010001000111ÄÄÄÄ1
|
||
BY 1
|
||
|
||
AFTER SHR 0ÄÄÄÄ00000000001000100010001000100010ÄÄÄÄO
|
||
BY 10
|
||
|
||
SHR SHIFTS THE BITS OF 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.
|
||
|
||
|
||
Figure 3-8. SAR
|
||
|
||
POSITIVE OPERAND CF
|
||
|
||
BEFORE SAR 01000100010001000100010001000111 X
|
||
|
||
AFTER SAR 0ÄÄÄÄ00100010001000100010001000100011ÄÄÄÄ1
|
||
BY 1
|
||
|
||
NEGATIVE OPERAND CF
|
||
|
||
BEFORE SAR 11000100010001000100010001000111 X
|
||
|
||
AFTER SAR 0ÄÄÄÄ11100010001000100010001000100011ÄÄÄÄ1
|
||
BY 1
|
||
|
||
SAR PRESERVES THE SIGN OF THE REGISTER OR MEMORY OPERAND AS IT SHIFTS THE
|
||
OPERAND TO THE RIGHT BY THE SPECIFIED NUMBER OF BIT POSITIONS. CF RECIEVES
|
||
THE LAST BIT SHIFTED OUT OF THE RIGHT OF THE OPERAND.
|
||
|
||
|
||
Figure 3-9. Using SAR to Simulate IDIV
|
||
|
||
; assuming N is in ECX, and the dividend is in EAX
|
||
; CLOCKS
|
||
CMP EAX, 0 ; to set sign flag 2
|
||
JGE NoAdjust ; jump if sign is zero 3 or 9
|
||
ADD EAX, ECX ; 2
|
||
DEC EAX ; EAX := EAX + (N-1) 2
|
||
NoAdjust:
|
||
SAR EAX, CL ; 3
|
||
; TOTAL CLOCKS 12 or 18]
|
||
|
||
|
||
3.4.4.2 Double-Shift Instructions
|
||
|
||
These instructions provide the basic operations needed to implement
|
||
operations on long unaligned bit strings. The double shifts operate either
|
||
on word or doubleword operands, as follows:
|
||
|
||
1. Taking two word operands as input and producing a one-word output.
|
||
|
||
2. Taking two doubleword operands as input and producing a doubleword
|
||
output.
|
||
|
||
Of the two input operands, one may either be in a general register or in
|
||
memory, while the other may only be in a general register. The results
|
||
replace the memory or register operand. The number of bits to be shifted is
|
||
specified either in the CL register or in an immediate byte of the
|
||
instruction.
|
||
|
||
Bits are shifted from the register operand into the memory or register
|
||
operand. CF is set to the value of the last bit shifted out of the
|
||
destination operand. SF, ZF, and PF are set according to the value of the
|
||
result. OF and AF are left undefined.
|
||
|
||
SHLD (Shift Left Double) shifts bits of the R/M field to the left, while
|
||
shifting high-order bits from the Reg field into the R/M field on the right
|
||
(see Figure 3-10). The result is stored back into the R/M operand. The Reg
|
||
field is not modified.
|
||
|
||
SHRD (Shift Right Double) shifts bits of the R/M field to the right, while
|
||
shifting low-order bits from the Reg field into the R/M field on the left
|
||
(see Figure 3-11). The result is stored back into the R/M operand. The Reg
|
||
field is not modified.
|
||
|
||
|
||
3.4.4.3 Rotate Instructions
|
||
|
||
Rotate instructions allow bits in bytes, words, and doublewords 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, word, or doubleword 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 exits from the left of the operand returns at the
|
||
right to become the new low-order bit of the operand. See Figure 3-12.
|
||
|
||
ROR (Rotate Right) rotates the byte, word, or doubleword 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-13.
|
||
|
||
RCL (Rotate Through Carry Left) rotates bits in the byte, word, or
|
||
doubleword 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
|
||
one-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-14.
|
||
|
||
RCR (Rotate Through Carry Right) rotates bits in the byte, word, or
|
||
doubleword 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
|
||
one-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-15.
|
||
|
||
|
||
Figure 3-10. Shift Left Double
|
||
|
||
31 DESTINATION 0
|
||
ÉÍÍÍÍ» ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º CF ºÄÄÄÄÄĶ MEMORY OF REGISTER ºÄÄÄ¿
|
||
ÈÍÍÍͼ ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ ³
|
||
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
||
³ 31 SOURCE 0
|
||
³ ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
ÀÄÄĶ REGISTER º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
|
||
Figure 3-11. Shift Right Double
|
||
|
||
31 SOURCE 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º REGISTER ÇÄÄÄ¿
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ ³
|
||
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
||
³ 31 DESTINATION 0
|
||
³ ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» ÉÍÍÍÍ»
|
||
ÀÄĺ MEMORY OF REGISTER ÇÄÄÄÄÄÄĺ CF º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ ÈÍÍÍͼ
|
||
|
||
|
||
Figure 3-12. ROL
|
||
|
||
31 DESTINATION 0
|
||
ÉÍÍÍÍ» ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º CF ºÄÄÄÂÄĶ MEMORY OF REGISTER ºÄÄ¿
|
||
ÈÍÍÍͼ ³ ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ ³
|
||
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
||
|
||
|
||
Figure 3-13. ROR
|
||
|
||
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
||
³ 31 DESTINATION 0 ³
|
||
³ ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» ³ ÉÍÍÍÍ»
|
||
ÀÄĺ MEMORY OF REGISTER ÇÄÄÄÁÄÄĺ CF º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ ÈÍÍÍͼ
|
||
|
||
|
||
Figure 3-14. RCL
|
||
|
||
31 DESTINATION 0
|
||
ÉÍÍÍÍ» ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
ÚĶ CF ºÄÄÄÄÄĶ MEMORY OF REGISTER ºÄÄ¿
|
||
³ ÈÍÍÍͼ ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ ³
|
||
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
||
|
||
|
||
Figure 3-15. RCR
|
||
|
||
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
||
³ 31 DESTINATION 0 ³
|
||
³ ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» ÉÍÍÍÍ» ³
|
||
ÀÄĺ MEMORY OF REGISTER ÇÄÄÄÄÄÄĺ CF ÇÄÙ
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ ÈÍÍÍͼ
|
||
|
||
|
||
3.4.4.4 Fast "BIT BLT" Using Double Shift Instructions
|
||
|
||
One purpose of the double shifts is to implement a bit string move, with
|
||
arbitrary misalignment of the bit strings. This is called a "bit blt" (BIT
|
||
BLock Transfer.) A simple example is to move a bit string from an arbitrary
|
||
offset into a doubleword-aligned byte string. A left-to-right string is
|
||
moved 32 bits at a time if a double shift is used inside the move loop.
|
||
|
||
MOV ESI,ScrAddr
|
||
MOV EDI,DestAddr
|
||
MOV EBX,WordCnt
|
||
MOV CL,RelOffset ; relative offset Dest-Src
|
||
MOV EDX,[ESI] ; load first word of source
|
||
ADD ESI,4 ; bump source address
|
||
BltLoop:
|
||
LODS ; new low order part
|
||
SHLD EDX,EAX,CL ; EDX overwritten with aligned stuff
|
||
XCHG EDX,EAS ; Swap high/low order parts
|
||
STOS ; Write out next aligned chunk
|
||
DEC EBX
|
||
JA BltLoop
|
||
|
||
This loop is simple yet allows the data to be moved in 32-bit pieces for
|
||
the highest possible performance. Without a double shift, the best that can
|
||
be achieved is 16 bits per loop iteration by using a 32-bit shift and
|
||
replacing the XCHG with a ROR by 16 to swap high and low order parts of
|
||
registers. A more general loop than shown above would require some extra
|
||
masking on the first doubleword moved (before the main loop), and on the
|
||
last doubleword moved (after the main loop), but would have the same basic
|
||
32-bits per loop iteration as the code above.
|
||
|
||
|
||
3.4.4.5 Fast Bit-String Insert and Extract
|
||
|
||
The double shift instructions also enable:
|
||
|
||
þ Fast insertion of a bit string from a register into an arbitrary bit
|
||
location in a larger bit string in memory without disturbing the bits
|
||
on either side of the inserted bits.
|
||
|
||
þ Fast extraction of a bits string into a register from an arbitrary bit
|
||
location in a larger bit string in memory without disturbing the bits
|
||
on either side of the extracted bits.
|
||
|
||
The following coded examples illustrate bit insertion and extraction under
|
||
variousconditions:
|
||
|
||
1. Bit String Insert into Memory (when bit string is 1-25 bits long,
|
||
i.e., spans four bytes or less):
|
||
|
||
; Insert a right-justified bit string from register into
|
||
; memory bit string.
|
||
;
|
||
; Assumptions:
|
||
; 1) The base of the string array is dword aligned, and
|
||
; 2) the length of the bit string is an immediate value
|
||
; but the bit offset is held in a register.
|
||
;
|
||
; Register ESI holds the right-justified bit string
|
||
; to be inserted.
|
||
; Register EDI holds the bit offset of the start of the
|
||
; substring.
|
||
; Registers EAX and ECX are also used by this
|
||
; "insert" operation.
|
||
;
|
||
MOV ECX,EDI ; preserve original offset for later use
|
||
SHR EDI,3 ; signed divide offset by 8 (byte address)
|
||
AND CL,7H ; isolate low three bits of offset in CL
|
||
MOV EAX,[EDI]strg_base ; move string dword into EAX
|
||
ROR EAX,CL ; right justify old bit field
|
||
SHRD EAX,ESI,length ; bring in new bits
|
||
ROL EAX,length ; right justify new bit field
|
||
ROL EAX,CL ; bring to final position
|
||
MOV [EDI]strg_base,EAX ; replace dword in memory
|
||
|
||
2. Bit String Insert into Memory (when bit string is 1-31 bits long, i.e.
|
||
spans five bytes or less):
|
||
|
||
; Insert a right-justified bit string from register into
|
||
; memory bit string.
|
||
;
|
||
; Assumptions:
|
||
; 1) The base of the string array is dword aligned, and
|
||
; 2) the length of the bit string is an immediate value
|
||
; but the bit offset is held in a register.
|
||
;
|
||
; Register ESI holds the right-justified bit string
|
||
; to be inserted.
|
||
; Register EDI holds the bit offset of the start of the
|
||
; substring.
|
||
; Registers EAX, EBX, ECX, and EDI are also used by
|
||
; this "insert" operation.
|
||
;
|
||
MOV ECX,EDI ; temp storage for offset
|
||
SHR EDI,5 ; signed divide offset by 32 (dword address)
|
||
SHL EDI,2 ; multiply by 4 (in byte address format)
|
||
AND CL,1FH ; isolate low five bits of offset in CL
|
||
MOV EAX,[EDI]strg_base ; move low string dword into EAX
|
||
MOV EDX,[EDI]strg_base+4 ; other string dword into EDX
|
||
MOV EBX,EAX ; temp storage for part of string ¿ rotate
|
||
SHRD EAX,EDX,CL ; double shift by offset within dword à EDX:EAX
|
||
SHRD EAX,EBX,CL ; double shift by offset within dword Ù right
|
||
SHRD EAX,ESI,length ; bring in new bits
|
||
ROL EAX,length ; right justify new bit field
|
||
MOV EBX,EAX ; temp storage for part of string ¿ rotate
|
||
SHLD EAX,EDX,CL ; double shift back by offset within word à EDX:EAX
|
||
SHLD EDX,EBX,CL ; double shift back by offset within word Ù left
|
||
MOV [EDI]strg_base,EAX ; replace dword in memory
|
||
MOV [EDI]strg_base+4,EDX ; replace dword in memory
|
||
|
||
3. Bit String Insert into Memory (when bit string is exactly 32 bits
|
||
long, i.e., spans five or four types of memory):
|
||
|
||
; Insert right-justified bit string from register into
|
||
; memory bit string.
|
||
;
|
||
; Assumptions:
|
||
; 1) The base of the string array is dword aligned, and
|
||
; 2) the length of the bit string is 32
|
||
; but the bit offset is held in a register.
|
||
;
|
||
; Register ESI holds the 32-bit string to be inserted.
|
||
; Register EDI holds the bit offset of the start of the
|
||
; substring.
|
||
; Registers EAX, EBX, ECX, and EDI are also used by
|
||
; this "insert" operation.
|
||
;
|
||
MOV EDX,EDI ; preserve original offset for later use
|
||
SHR EDI,5 ; signed divide offset by 32 (dword address)
|
||
SHL EDI,2 ; multiply by 4 (in byte address format)
|
||
AND CL,1FH ; isolate low five bits of offset in CL
|
||
MOV EAX,[EDI]strg_base ; move low string dword into EAX
|
||
MOV EDX,[EDI]strg_base+4 ; other string dword into EDX
|
||
MOV EBX,EAX ; temp storage for part of string ¿ rotate
|
||
SHRD EAX,EDX ; double shift by offset within dword à EDX:EAX
|
||
SHRD EDX,EBX ; double shift by offset within dword Ù right
|
||
MOV EAX,ESI ; move 32-bit bit field into position
|
||
MOV EBX,EAX ; temp storage for part of string ¿ rotate
|
||
SHLD EAX,EDX ; double shift back by offset within word à EDX:EAX
|
||
SHLD EDX,EBX ; double shift back by offset within word Ù left
|
||
MOV [EDI]strg_base,EAX ; replace dword in memory
|
||
MOV [EDI]strg_base,+4,EDX ; replace dword in memory
|
||
|
||
4. Bit String Extract from Memory (when bit string is 1-25 bits long,
|
||
i.e., spans four bytes or less):
|
||
|
||
; Extract a right-justified bit string from memory bit
|
||
; string into register
|
||
;
|
||
; Assumptions:
|
||
; 1) The base of the string array is dword aligned, and
|
||
; 2) the length of the bit string is an immediate value
|
||
; but the bit offset is held in a register.
|
||
;
|
||
; Register EAX holds the right-justified, zero-padded
|
||
; bit string that was extracted.
|
||
; Register EDI holds the bit offset of the start of the
|
||
; substring.
|
||
; Registers EDI, and ECX are also used by this "extract."
|
||
;
|
||
MOV ECX,EDI ; temp storage for offset
|
||
SHR EDI,3 ; signed divide offset by 8 (byte address)
|
||
AND CL,7H ; isolate low three bits of offset
|
||
MOV EAX,[EDI]strg_base ; move string dword into EAX
|
||
SHR EAX,CL ; shift by offset within dword
|
||
AND EAX,mask ; extracted bit field in EAX
|
||
|
||
5. Bit String Extract from Memory (when bit string is 1-32 bits long,
|
||
i.e., spans five bytes or less):
|
||
|
||
; Extract a right-justified bit string from memory bit
|
||
; string into register.
|
||
;
|
||
; Assumptions:
|
||
; 1) The base of the string array is dword aligned, and
|
||
; 2) the length of the bit string is an immediate
|
||
; value but the bit offset is held in a register.
|
||
;
|
||
; Register EAX holds the right-justified, zero-padded
|
||
; bit string that was extracted.
|
||
; Register EDI holds the bit offset of the start of the
|
||
; substring.
|
||
; Registers EAX, EBX, and ECX are also used by this "extract."
|
||
MOV ECX,EDI ; temp storage for offset
|
||
SHR EDI,5 ; signed divide offset by 32 (dword address)
|
||
SHL EDI,2 ; multiply by 4 (in byte address format)
|
||
AND CL,1FH ; isolate low five bits of offset in CL
|
||
MOV EAX,[EDI]strg_base ; move low string dword into EAX
|
||
MOV EDX,[EDI]strg_base+4 ; other string dword into EDX
|
||
SHRD EAX,EDX,CL ; double shift right by offset within dword
|
||
AND EAX,mask ; extracted bit field in EAX
|
||
|
||
|
||
3.4.5 Byte-Set-On-Condition Instructions
|
||
|
||
This group of instructions sets a byte to zero or one depending on any of
|
||
the 16 conditions defined by the status flags. The byte may be in memory or
|
||
may be a one-byte general register. These instructions are especially useful
|
||
for implementing Boolean expressions in high-level languages such as Pascal.
|
||
|
||
SETcc (Set Byte on Condition cc) set a byte to one if condition cc is true;
|
||
sets the byte to zero otherwise. Refer to Appendix D for a definition of
|
||
the possible conditions.
|
||
|
||
|
||
3.4.6 Test Instruction
|
||
|
||
TEST (Test) performs the logical "and" of the two operands, clears OF and
|
||
CF, leaves AF undefined, and updates SF, ZF, and PF. The flags can be tested
|
||
by conditional control transfer instructions or by the byte-set-on-condition
|
||
instructions. The operands may be doublewords, words, or bytes.
|
||
|
||
The difference between TEST and AND is that TEST does not alter the
|
||
destination operand. TEST differs from BT in that TEST is useful for testing
|
||
the value of multiple bits in one operations, whereas BT tests a single bit.
|
||
|
||
|
||
3.5 Control Transfer Instructions
|
||
|
||
The 80386 provides both conditional and unconditional control transfer
|
||
instructions to direct the flow of execution. Conditional control transfers
|
||
depend on the results of operations that affect the flag register.
|
||
Unconditional control transfers are always executed.
|
||
|
||
|
||
3.5.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 (near control transfers) or in different code segments (far control
|
||
transfers). The variants of these instructions that transfer control to
|
||
other segments are discussed in a later section of this chapter. If the
|
||
model of memory organization used in a particular 80386 application does
|
||
not make segments visible to applications programmers, intersegment control
|
||
transfers will not be used.
|
||
|
||
|
||
3.5.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 whether the address is specified directly within the
|
||
instruction or indirectly through a register or memory.
|
||
|
||
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.
|
||
|
||
Direct near JMP. A direct JMP uses a relative displacement value contained
|
||
in the instruction. The displacement is signed and the size of the
|
||
displacement may be a byte, word, or doubleword. The processor forms an
|
||
effective address by adding this relative displacement to the address
|
||
contained in EIP. When the additions have been performed, EIP refers to the
|
||
next instruction to be executed.
|
||
|
||
Indirect near JMP. Indirect JMP instructions specify an absolute address in
|
||
one of several ways:
|
||
|
||
1. The program can JMP to a location specified by a general register
|
||
(any of EAX, EDX, ECX, EBX, EBP, ESI, or EDI). The processor moves
|
||
this 32-bit value into EIP and resumes execution.
|
||
|
||
2. The processor can obtain the destination address from a memory
|
||
operand specified in the instruction.
|
||
|
||
3. A register can modify the address of the memory pointer to select a
|
||
destination address.
|
||
|
||
|
||
3.5.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. CALL places the current value of EIP on the stack.
|
||
The RET instruction in the called procedure uses this address to transfer
|
||
control back to the calling program.
|
||
|
||
CALL instructions, like JMP instructions have relative, direct, and
|
||
indirect versions.
|
||
|
||
Indirect CALL instructions specify an absolute address in one of these
|
||
ways:
|
||
|
||
1. The program can CALL a location specified by a general register (any
|
||
of EAX, EDX, ECX, EBX, EBP, ESI, or EDI). The processor moves this
|
||
32-bit value into EIP.
|
||
|
||
2. The processor can obtain the destination address from a memory
|
||
operand specified in the instruction.
|
||
|
||
|
||
3.5.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. RET restores the value of EIP that was
|
||
saved on the stack by the previous CALL instruction.
|
||
|
||
RET instructions may optionally specify an immediate operand. By adding
|
||
this constant to the new top-of-stack pointer, RET effectively removes any
|
||
arguments that the calling program pushed on the stack before the execution
|
||
of the CALL instruction.
|
||
|
||
IRET (Return From Interrupt) returns control to an interrupted procedure.
|
||
IRET differs from RET in that it also pops the flags from the stack into the
|
||
flags register. The flags are stored on the stack by the interrupt
|
||
mechanism.
|
||
|
||
|
||
3.5.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.
|
||
|
||
|
||
3.5.2.1 Conditional Jump Instructions
|
||
|
||
Table 3-2 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.
|
||
|
||
Conditional jump instructions contain a displacement which is added to the
|
||
EIP register if the condition is true. The displacement may be a byte, a
|
||
word, or a doubleword. The displacement is signed; therefore, it can be used
|
||
to jump forward or backward.
|
||
|
||
|
||
Table 3-2. 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) = 1 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.5.2.2 Loop Instructions
|
||
|
||
The loop instructions are conditional jumps that use a value placed in ECX
|
||
to specify the number of repetitions of a software loop. All loop
|
||
instructions automatically decrement ECX and terminate the loop when ECX=0.
|
||
Four of the five loop instructions specify a condition involving ZF that
|
||
terminates the loop before ECX reaches zero.
|
||
|
||
LOOP (Loop While ECX Not Zero) is a conditional transfer that automatically
|
||
decrements the ECX register before testing ECX for the branch condition. If
|
||
ECX 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 ECX to a value of
|
||
zero. If LOOP finds ECX=0, control transfers to the instruction immediately
|
||
following the LOOP instruction. If the value of ECX is initially zero, then
|
||
the LOOP executes 2^(32) times.
|
||
|
||
LOOPE (Loop While Equal) and LOOPZ (Loop While Zero) are synonyms for the
|
||
same instruction. These instructions automatically decrement the ECX
|
||
register before testing ECX and ZF for the branch conditions. If ECX is
|
||
non-zero and ZF=1, the program branches to the target label specified in the
|
||
instruction. If LOOPE or LOOPZ finds that ECX=0 or ZF=0, control transfers
|
||
to the instruction immediately following the LOOPE or LOOPZ instruction.
|
||
|
||
LOOPNE (Loop While Not Equal) and LOOPNZ (Loop While Not Zero) are synonyms
|
||
for the same instruction. These instructions automatically decrement the ECX
|
||
register before testing ECX and ZF for the branch conditions. If ECX is
|
||
non-zero and ZF=0, the program branches to the target label specified in the
|
||
instruction. If LOOPNE or LOOPNZ finds that ECX=0 or ZF=1, control transfers
|
||
to the instruction immediately following the LOOPNE or LOOPNZ instruction.
|
||
|
||
|
||
3.5.2.3 Executing a Loop or Repeat Zero Times
|
||
|
||
JCXZ (Jump if ECX Zero) branches to the label specified in the instruction
|
||
if it finds a value of zero in ECX. JCXZ is useful in combination with the
|
||
LOOP instruction and with the string scan and compare instructions, all of
|
||
which decrement ECX. Sometimes, it is desirable to design a loop that
|
||
executes zero times if the count variable in ECX is initialized to zero.
|
||
Because the LOOP instructions (and repeat prefixes) decrement ECX before
|
||
they test it, a loop will execute 2^(32) times if the program enters the
|
||
loop with a zero value in ECX. A programmer may conveniently overcome this
|
||
problem with JCXZ, which enables the program to branch around the code
|
||
within the loop if ECX is zero when JCXZ executes. When used with repeated
|
||
string scan and compare instructions, JCXZ can determine whether the
|
||
repetitions terminated due to zero in ECX or due to satisfaction of the
|
||
scan or compare conditions.
|
||
|
||
|
||
3.5.3 Software-Generated Interrupts
|
||
|
||
The INT n, INTO, and BOUND instructions allow the programmer to specify a
|
||
transfer to an interrupt service routine from within a program.
|
||
|
||
INT n (Software Interrupt) activates the interrupt service routine that
|
||
corresponds to the number coded within the instruction. The INT instruction
|
||
may specify any interrupt type. Programmers may use this flexibility to
|
||
implement multiple types of internal interrupts or to test the operation of
|
||
interrupt service routines. (Interrupts 0-31 are reserved by Intel.) The
|
||
interrupt service routine terminates with an IRET instruction that returns
|
||
control to the instruction that follows INT.
|
||
|
||
INTO (Interrupt on Overflow) invokes interrupt 4 if OF is set. Interrupt 4
|
||
is reserved for this purpose. OF is set by several arithmetic, logical, and
|
||
string instructions.
|
||
|
||
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 the upper limit and lower limit are in adjacent memory
|
||
locations. 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 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 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.
|
||
|
||
The upper and lower limit values may each be a word or a doubleword.
|
||
|
||
|
||
3.6 String and Character Translation Instructions
|
||
|
||
The instructions in this category operate on strings rather than on logical
|
||
or numeric values. Refer also to the section on I/O for information about
|
||
the string I/O instructions (also known as block I/O).
|
||
|
||
The power of 80386 string operations derives from the following features of
|
||
the architecture:
|
||
|
||
1. A set of primitive string operations
|
||
|
||
MOVS ÄÄ Move String
|
||
CMPS ÄÄ Compare string
|
||
SCAS ÄÄ Scan string
|
||
LODS ÄÄ Load string
|
||
STOS ÄÄ Store string
|
||
|
||
2. Indirect, indexed addressing, with automatic incrementing or
|
||
decrementing of the indexes.
|
||
|
||
Indexes:
|
||
|
||
ESI ÄÄ Source index register
|
||
EDI ÄÄ Destination index register
|
||
|
||
Control flag:
|
||
|
||
DF ÄÄ Direction flag
|
||
|
||
Control flag instructions:
|
||
|
||
CLD ÄÄ Clear direction flag instruction
|
||
STD ÄÄ Set direction flag instruction
|
||
|
||
3. Repeat prefixes
|
||
|
||
REP ÄÄ Repeat while ECX not xero
|
||
REPE/REPZ ÄÄ Repeat while equal or zero
|
||
REPNE/REPNZ ÄÄ Repeat while not equal or not zero
|
||
|
||
The primitive string operations operate on one element of a string. A
|
||
string element may be a byte, a word, or a doubleword. The string elements
|
||
are addressed by the registers ESI and EDI. After every primitive operation
|
||
ESI and/or EDI are automatically updated to point to the next element of the
|
||
string. If the direction flag is zero, the index registers are incremented;
|
||
if one, they are decremented. The amount of the increment or decrement is
|
||
1, 2, or 4 depending on the size of the string element.
|
||
|
||
|
||
3.6.1 Repeat Prefixes
|
||
|
||
The repeat prefixes REP (Repeat While ECX Not Zero), REPE/REPZ (Repeat
|
||
While Equal/Zero), and REPNE/REPNZ (Repeat While Not Equal/Not Zero) specify
|
||
repeated operation of a string primitive. This form of iteration allows the
|
||
CPU to process strings much faster than would be possible with a regular
|
||
software loop.
|
||
|
||
When a primitive string operation has a repeat prefix, the operation is
|
||
executed repeatedly, each time using a different element of the string. The
|
||
repetition terminates when one of the conditions specified by the prefix is
|
||
satisfied.
|
||
|
||
At each repetition of the primitive instruction, the string operation may
|
||
be suspended temporarily in order to handle an exception or external
|
||
interrupt. After the interruption, the string operation can be restarted
|
||
again where it left off. This method of handling strings allows operations
|
||
on strings of arbitrary length, without affecting interrupt response.
|
||
|
||
All three prefixes causes the hardware to automatically repeat the
|
||
associated string primitive until ECX=0. The differences among the repeat
|
||
prefixes have to do with the second termination condition. REPE/REPZ and
|
||
REPNE/REPNZ are used exclusively with the SCAS (Scan String) and CMPS
|
||
(Compare String) primitives. When these prefixes are used, repetition of the
|
||
next instruction depends on the zero flag (ZF) as well as the ECX register.
|
||
ZF does not require initialization before execution of a repeated string
|
||
instruction, because both SCAS and CMPS set ZF according to the results of
|
||
the comparisons they make. The differences are summarized in the
|
||
accompanying table.
|
||
|
||
Prefix Termination Termination
|
||
Condition 1 Condition 2
|
||
|
||
REP ECX = 0 (none)
|
||
REPE/REPZ ECX = 0 ZF = 0
|
||
REPNE/REPNZ ECX = 0 ZF = 1
|
||
|
||
|
||
3.6.2 Indexing and Direction Flag Control
|
||
|
||
The addresses of the operands of string primitives are determined by the
|
||
ESI and EDI registers. ESI points to source operands. By default, ESI refers
|
||
to a location in the segment indicated by the DS segment register. A
|
||
segment-override prefix may be used, however, to cause ESI to refer to CS,
|
||
SS, ES, FS, or GS. EDI points to destination operands in the segment
|
||
indicated by ES; no segment override is possible. The use of two different
|
||
segment registers in one instruction allows movement of strings between
|
||
different segments.
|
||
|
||
This use of ESI and DSI has led to the descriptive names source index and
|
||
destination index for the ESI and EDI registers, respectively. In all
|
||
cases other than string instructions, however, the ESI and EDI registers may
|
||
be used as general-purpose registers.
|
||
|
||
When ESI and EDI are used in string primitives, they are automatically
|
||
incremented or decremented after to operation. The direction flag determines
|
||
whether they are incremented or decremented. The instruction CLD puts zero
|
||
in DF, causing the index registers to be incremented; the instruction STD
|
||
puts one in DF, causing the index registers to be decremented. Programmers
|
||
should always put a known value in DF before using string instructions in a
|
||
procedure.
|
||
|
||
|
||
3.6.3 String Instructions
|
||
|
||
MOVS (Move String) moves the string element pointed to by ESI to the
|
||
location pointed to by EDI. MOVSB operates on byte elements, MOVSW operates
|
||
on word elements, and MOVSD operates on doublewords. The destination segment
|
||
register cannot be overridden by a segment override prefix, but the source
|
||
segment register can be overridden.
|
||
|
||
The MOVS instruction, when accompanied by the REP prefix, operates as a
|
||
memory-to-memory block transfer. To set up for this operation, the program
|
||
must initialize ECX and the register pairs ESI and EDI. ECX specifies the
|
||
number of bytes, words, or doublewords in the block.
|
||
|
||
If DF=0, the program must point ESI to the first element of the source
|
||
string and point EDI to the destination address for the first element. If
|
||
DF=1, the program must point these two registers to the last element of the
|
||
source string and to the destination address for the last element,
|
||
respectively.
|
||
|
||
CMPS (Compare Strings) subtracts the destination string element (at ES:EDI)
|
||
from the source string element (at ESI) 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 (ESI and EDI) for the two
|
||
strings. CMPSB compares bytes, CMPSW compares words, and CMPSD compares
|
||
doublewords. The segment register used for the source address can be changed
|
||
with a segment override prefix while the destination segment register
|
||
cannot be overridden.
|
||
|
||
SCAS (Scan String) subtracts the destination string element at ES:EDI from
|
||
EAX, 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 (EDI) for the string. SCASB scans bytes; SCASW scans
|
||
words; SCASD scans doublewords. The destination segment register (ES) cannot
|
||
be overridden.
|
||
|
||
When either the REPE or REPNE prefix modifies either the SCAS or CMPS
|
||
primitives, the processor compares the value of the current string element
|
||
with the value in EAX for doubleword elements, in AX for word elements, or
|
||
in AL for byte elements. Termination of the repeated operation depends on
|
||
the resulting state of ZF as well as on the value in ECX.
|
||
|
||
LODS (Load String) places the source string element at ESI into EAX for
|
||
doubleword strings, into AX for word strings, or into AL for byte strings.
|
||
LODS increments or decrements ESI according to DF.
|
||
|
||
STOS (Store String) places the source string element from EAX, AX, or AL
|
||
into the string at ES:DSI. STOS increments or decrements EDI according to
|
||
DF.
|
||
|
||
|
||
3.7 Instructions for Block-Structured Languages
|
||
|
||
The instructions in this section provide machine-language support for
|
||
functions normally found in high-level languages. These instructions include
|
||
ENTER and LEAVE, which simplify the programming of procedures.
|
||
|
||
ENTER (Enter Procedure) creates a stack frame that may be used to implement
|
||
the scope rules of 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.
|
||
|
||
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.
|
||
|
||
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.
|
||
|
||
After ENTER creates the new display for a procedure, it allocates the
|
||
dynamic storage space for that procedure by decrementing ESP by the number
|
||
of bytes specified in the first parameter. This new value of ESP serves as a
|
||
starting point for all PUSH and POP operations within that procedure.
|
||
|
||
To enable a procedure to address its display, ENTER leaves EBP pointing to
|
||
the beginning of the new stack frame. Data manipulation instructions that
|
||
specify EBP as a base register implicitly address locations within the stack
|
||
segment instead of the data segment.
|
||
|
||
The ENTER instruction can be used in two ways: nested and non-nested. If
|
||
the lexical level is 0, the non-nested form is used. Since the second
|
||
operand is 0, ENTER pushes EBP, copies ESP to EBP and then subtracts the
|
||
first operand from ESP. The nested form of ENTER occurs when the second
|
||
parameter (lexical level) is not 0.
|
||
|
||
Figure 3-16 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
|
||
3-17). Figures 3-18 through 3-21 demonstrate the actions of the ENTER
|
||
instruction if the modules shown in Figure 3-17 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.
|
||
Referring to Figure 3-17 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 access to
|
||
variables for Figure 3-17.
|
||
|
||
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
|
||
EBP. See Figure 3-18.
|
||
|
||
After MAIN calls PROCEDURE A, ENTER creates a new display for PROCEDURE A
|
||
with the first word pointing to the previous value of EBP (BPM for LEAVE to
|
||
return to the MAIN stack frame) and the second word pointing to the current
|
||
value of EBP. Procedure A can access variables in MAIN since MAIN is at
|
||
level 1. Therefore the base for the dynamic storage for MAIN is at [EBP-2].
|
||
All dynamic variables for MAIN are at a fixed offset from this value. See
|
||
Figure 3-19.
|
||
|
||
After PROCEDURE A calls PROCEDURE B, ENTER creates a new display for
|
||
PROCEDURE B with the first word pointing to the previous value of EBP, the
|
||
second word pointing to the value of EBP for MAIN, and the third word
|
||
pointing to the value of EBP for A and the last word pointing to the current
|
||
EBP. B can access variables in A and MAIN by fetching from the display the
|
||
base addresses of the respective dynamic storage areas. See Figure 3-20.
|
||
|
||
After PROCEDURE B calls PROCEDURE C, ENTER creates a new display for
|
||
PROCEDURE C with the first word pointing to the previous value of EBP, the
|
||
second word pointing to the value of EBP for MAIN, and the third word
|
||
pointing to the EBP value for A and the third word pointing to the current
|
||
value of EBP. 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 3-21.
|
||
|
||
LEAVE (Leave Procedure) reverses the action of the previous ENTER
|
||
instruction. The LEAVE instruction does not include any operands. LEAVE
|
||
copies EBP to ESP to release all stack space allocated to the procedure by
|
||
the most recent ENTER instruction. Then LEAVE pops the old value of EBP 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.
|
||
|
||
|
||
Figure 3-16. 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 EBP
|
||
Set a temporary value FRAME_PTR := ESP
|
||
If LEVEL > 0 then
|
||
Repeat (LEVEL-1) times:
|
||
EBP :=EBP - 4
|
||
Push the doubleword pointed to by EBP
|
||
End repeat
|
||
Push FRAME_PTR
|
||
End if
|
||
EBP := FRAME_PTR
|
||
ESP := ESP - first operand.
|
||
|
||
|
||
Figure 3-17. Variable Access in Nested Procedures
|
||
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º MAIN PROCEDURE (LEXICAL LEVEL 1) º
|
||
º ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» º
|
||
º º PROCEDURE A (LEXICAL LEVEL 2) º º
|
||
º º ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» º º
|
||
º º º PROCEDURE B (LEXICAL LEVEL 3) º º º
|
||
º º ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ º º
|
||
º º º º
|
||
º º ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» º º
|
||
º º º PROCEDURE C (LEXICAL LEVEL 3) º º º
|
||
º º º ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» º º º
|
||
º º º º PROCEDURE D (LEXICAL LEVEL 4) º º º º
|
||
º º º ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ º º º
|
||
º º º º º º
|
||
º º ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ º º
|
||
º º º º
|
||
º ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ º
|
||
º º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
|
||
Figure 3-18. Stack Frame for MAIN at Level 1
|
||
|
||
31 0
|
||
D O º º
|
||
I F ÚÄ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
R ³ º OLD ESP º
|
||
E E DISPLAY Ä´ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ÄÄEBP FOR
|
||
C X ³ º EBPM
|
||
EBPM = EBP VALUE FOR MAIN º MAIN
|
||
T P ÆÍ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
I A ³ º º
|
||
O N ³ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
N S DYNAMIC Ä´ º º
|
||
I STORAGE ³ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
³ O ³ º º
|
||
³ N ÀÄ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ÄÄESP
|
||
³ º º
|
||
|
||
|
||
|
||
Figure 3-19. Stack Frame for Procedure A
|
||
|
||
31 0
|
||
D O º º
|
||
I F ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
R º OLD ESP º
|
||
E E ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
C X º EBPM
|
||
EBPM = EBP VALUE FOR MAIN º
|
||
T P ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
I A º º
|
||
O N ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
N S º º
|
||
I ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
³ O º º
|
||
³ N ÚÄ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
³ ³ º EBPM º
|
||
³ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ÄÄEBP FOR A
|
||
DISPLAY Ä´ º EBPM º
|
||
³ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
³ º EBPA
|
||
EBPA = EBP VALUE FOR PROCEDURE A º
|
||
ÆÍ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
³ º º
|
||
³ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
DYNAMIC Ä´ º º
|
||
STORAGE ³ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
³ º º
|
||
ÀÄ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ÄÄESP
|
||
º º
|
||
|
||
|
||
|
||
Figure 3-20. Stack Frame for Procedure B at Level 3 Called from A
|
||
|
||
31 0
|
||
D O º º
|
||
I F ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
R º OLD ESP º
|
||
E E ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
C X º EBPM
|
||
EBPM = EBP VALUE FOR MAIN º
|
||
T P ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
I A º º
|
||
O N ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
N S º º
|
||
I ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
³ O º º
|
||
³ N ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
³ º EBPM º
|
||
ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
º EBPM º
|
||
ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
º EBPA º
|
||
ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
º º
|
||
ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
º º
|
||
ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
º º
|
||
ÚÄ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
³ º EBPA º
|
||
³ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ÄÄEBP
|
||
³ º EBPM º
|
||
DISPLAY Ä´ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
³ º EBPA º
|
||
³ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
³ º EBPB
|
||
EBPB = EBP VALUE FOR PROCEDURE B º
|
||
ÆÍ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
³ º º
|
||
³ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
DYNAMIC Ä´ º º
|
||
STORAGE ³ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
³ º º
|
||
ÀÄ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ÄÄESP
|
||
º º
|
||
|
||
|
||
|
||
Figure 3-21. Stack Frame for Procedure C at Level 3 Called from B
|
||
|
||
31 0
|
||
D O º º
|
||
I F ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
R º OLD ESP º
|
||
E E ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
C X º EBPM
|
||
EBPM = EBP VALUE FOR MAIN º
|
||
T P ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
I A º º
|
||
O N ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
N S º º
|
||
I ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
³ O º º
|
||
³ N ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
³ º EBPM º
|
||
ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
º EBPM º
|
||
ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
º EBPA
|
||
EBPA = EBP VALUE FOR PROCEDURE A º
|
||
ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
º º
|
||
ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
º º
|
||
ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
º º
|
||
ÚÄ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
³ º EBPA º
|
||
³ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ÄÄEBP
|
||
³ º EBPM º
|
||
DISPLAY Ä´ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
³ º EBPA º
|
||
³ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
³ º EBPB
|
||
EBPB = EBP VALUE FOR PROCEDURE B º
|
||
ÆÍ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
³ º º
|
||
³ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
DYNAMIC Ä´ º º
|
||
STORAGE ³ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
³ º º
|
||
ÀÄ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ÄÄESP
|
||
º º
|
||
|
||
|
||
|
||
3.8 Flag Control Instructions
|
||
|
||
The flag control instructions provide a method for directly changing the
|
||
state of bits in the flag register.
|
||
|
||
|
||
3.8.1 Carry and Direction 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.
|
||
|
||
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 index registers, ESI and EDI, after each
|
||
execution of a string primitive. If DF=1, the processor decrements these
|
||
index registers. Programmers should use one of these instructions before any
|
||
procedure that uses string instructions to insure that DF is set properly.
|
||
|
||
Flag Control Instruction Effect
|
||
|
||
STC (Set Carry Flag) CF 1
|
||
CLC (Clear Carry Flag) CF 0
|
||
CMC (Complement Carry Flag) CF NOT (CF)
|
||
CLD (Clear Direction Flag) DF 0
|
||
STD (Set Direction Flag) DF 1
|
||
|
||
|
||
3.8.2 Flag Transfer Instructions
|
||
|
||
Though specific instructions exist to alter CF and DF, there is no direct
|
||
method of altering the other applications-oriented 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 instructions LAHF and SAHF deal with five of the status flags, which
|
||
are used primarily by the arithmetic and logical instructions.
|
||
|
||
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-22). The contents of the remaining bits
|
||
(5, 3, and 1) are undefined. The flags remain unaffected.
|
||
|
||
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-22).
|
||
|
||
The PUSHF and POPF instructions are not only useful for storing the flags
|
||
in memory where they can be examined and modified but are also useful for
|
||
preserving the state of the flags register while executing a procedure.
|
||
|
||
PUSHF (Push Flags) decrements ESP by two and then transfers the low-order
|
||
word of the flags register to the word at the top of stack pointed to by ESP
|
||
(see Figure 3-23). The variant PUSHFD decrements ESP by four, then
|
||
transfers both words of the extended flags register to the top of the stack
|
||
pointed to by ESP (the VM and RF flags are not moved, however).
|
||
|
||
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-23), then
|
||
increments ESP by two. The variant POPFD transfers specific bits from the
|
||
doubleword at the top of the stack into the extended flags register (the RF
|
||
and VM flags are not changed, however), then increments ESP by four.
|
||
|
||
|
||
Figure 3-22. LAHF and SAHF
|
||
|
||
7 6 5 4 3 2 1 0
|
||
ÉÍÍÍÍËÍÍÍÍËÍÍÍÍËÍÍÍÍËÍÍÍÍËÍÍÍÍËÍÍÍÍËÍÍÍÍ»
|
||
º SF º ZF º UU º AF º UU º PF º UU º CF º
|
||
ÈÍÍÍÍÊÍÍÍÍÊÍÍÍÍÊÍÍÍÍÊÍÍÍÍÊÍÍÍÍÊÍÍÍÍÊÍÍÍͼ
|
||
|
||
LAHF LOADS FIVE FLAGS FROM THE FLAG REGISTER INTO REGISTER AH. SAHF
|
||
STORES THESE SAME FIVE FLAGS 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 (MARKED UU) ARE RESERVED; DO NOT DEFINE.
|
||
|
||
|
||
3.9 Coprocessor Interface Instructions
|
||
|
||
A numerics coprocessor (e.g., the 80387 or 80287) provides an extension to
|
||
the instruction set of the base architecture. The coprocessor extends the
|
||
instruction set of the base architecture to support high-precision integer
|
||
and floating-point calculations. This extended instruction set includes
|
||
arithmetic, comparison, transcendental, and data transfer instructions. The
|
||
coprocessor also contains a set of useful constants to enhance the speed of
|
||
numeric calculations.
|
||
|
||
A program contains instructions for the coprocessor 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 coprocessor operates
|
||
concurrently with the CPU to provide maximum throughput for numeric
|
||
calculations.
|
||
|
||
The 80386 also has features to support emulation of the numerics
|
||
coprocessor when the coprocessor is absent. The software emulation of the
|
||
coprocessor is transparent to application software but requires more time
|
||
for execution. Refer to Chapter 11 for more information on coprocessor
|
||
emulation.
|
||
|
||
ESC (Escape) is a 5-bit sequence that begins the opcodes that identify
|
||
floating point numeric instructions. The ESC pattern tells the 80386 to send
|
||
the opcode and addresses of operands to the numerics coprocessor. The
|
||
numerics coprocessor uses the escape instructions to perform
|
||
high-performance, high-precision floating point arithmetic that conforms to
|
||
the IEEE floating point standard 754.
|
||
|
||
WAIT (Wait) is an 80386 instruction that suspends program execution until
|
||
the 80386 CPU detects that the BUSY pin is inactive. This condition
|
||
indicates that the coprocessor has completed its processing task and that
|
||
the CPU may obtain the results.
|
||
|
||
|
||
Figure 3-23. Flag Format for PUSHF and POPF
|
||
|
||
PUSHFD/POPFD
|
||
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
||
PUSHF/POPF
|
||
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
||
31 23 15 7 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÑÍÑÍÑÍÑÍÑÍÍÍÍÑÍÑÍÑÍÑÍÑÍÑÍÑÍÑÍÑÍÑÍÑÍÑÍ»
|
||
º ³V³R³ ³N³ID ³O³D³I³T³S³Z³ ³A³ ³P³ ³Cº
|
||
º0 0 0 0 0 0 0 0 0 0 0 0 0 0³ ³ ³0³ ³ ³ ³ ³ ³ ³ ³ ³0³ ³0³ ³1³ º
|
||
º ³M³F³ ³T³ PL³F³F³F³F³F³F³ ³F³ ³F³ ³Fº
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÏÍÏÍÏÍÏÍÏÍÍÍÍÏÍÏÍÏÍÏÍÏÍÏÍÏÍÏÍÏÍÏÍÏÍÏͼ
|
||
|
||
BITS MARKED 0 AND 1 ARE RESERVED BY INTEL. DO NOT DEFINE.
|
||
|
||
SYSTEMS FLAGS (INCLUDING THE IOPL FIELD, AND THE VM, RF, AND IF FLAGS)
|
||
ARE PUSHED AND ARE VISIBLE TO APPLICATIONS PROGRAMS. HOWEVER, WHEN AN
|
||
APPLICATIONS PROGRAM POPS THE FLAGS, THESE ITEMS ARE NOT CHANGED,
|
||
REGARDLESS OF THE VALUES POPPED INTO THEM.
|
||
|
||
|
||
3.10 Segment Register Instructions
|
||
|
||
This category actually includes several distinct types of instructions.
|
||
These various types are grouped together here because, if systems designers
|
||
choose an unsegmented model of memory organization, none of these
|
||
instructions is used by applications programmers. The instructions that deal
|
||
with segment registers are:
|
||
|
||
1. Segment-register transfer instructions.
|
||
|
||
MOV SegReg, ...
|
||
MOV ..., SegReg
|
||
PUSH SegReg
|
||
POP SegReg
|
||
|
||
2. Control transfers to another executable segment.
|
||
|
||
JMP far ; direct and indirect
|
||
CALL far
|
||
RET far
|
||
|
||
3. Data pointer instructions.
|
||
|
||
LDS
|
||
LES
|
||
LFS
|
||
LGS
|
||
LSS
|
||
|
||
Note that the following interrupt-related instructions are different; all
|
||
are capable of transferring control to another segment, but the use of
|
||
segmentation is not apparent to the applications programmer.
|
||
|
||
INT n
|
||
INTO
|
||
BOUND
|
||
IRET
|
||
|
||
|
||
3.10.1 Segment-Register Transfer Instructions
|
||
|
||
The MOV, POP, and PUSH instructions also serve to load and store segment
|
||
registers. These variants operate similarly to their general-register
|
||
counterparts except that one operand can be a segment register. MOV cannot
|
||
move segment register to a segment register. Neither POP nor MOV can place a
|
||
value in the code-segment register CS; only the far control-transfer
|
||
instructions can change CS.
|
||
|
||
|
||
3.10.2 Far Control Transfer Instructions
|
||
|
||
The far control-transfer instructions transfer control to a location in
|
||
another segment by changing the content of the CS register.
|
||
|
||
Direct far JMP. Direct JMP instructions that specify a target location
|
||
outside the current code segment contain a far pointer. This pointer
|
||
consists of a selector for the new code segment and an offset within the new
|
||
segment.
|
||
|
||
Indirect far JMP. Indirect JMP instructions that specify a target location
|
||
outside the current code segment use a 48-bit variable to specify the far
|
||
pointer.
|
||
|
||
Far CALL. An intersegment CALL places both the value of EIP and CS on the
|
||
stack.
|
||
|
||
Far RET. An intersegment RET restores the values of both CS and EIP which
|
||
were saved on the stack by the previous intersegment CALL instruction.
|
||
|
||
|
||
3.10.3 Data Pointer Instructions
|
||
|
||
The data pointer instructions load a pointer (consisting of a segment
|
||
selector and an offset) to a segment register and a general register.
|
||
|
||
LDS (Load Pointer Using DS) transfers a 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 general register. DS
|
||
receives the segment-selector of the pointer. The destination register
|
||
receives the offset part of the pointer, which points to a specific location
|
||
within the segment.
|
||
|
||
Example: LDS ESI, STRING_X
|
||
|
||
Loads DS with the selector identifying the segment pointed to by a
|
||
STRING_X, and loads the offset of STRING_X into ESI. Specifying ESI 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 segment selector rather than DS.
|
||
|
||
Example: LES EDI, DESTINATION_X
|
||
|
||
Loads ES with the selector identifying the segment pointed to by
|
||
DESTINATION_X, and loads the offset of DESTINATION_X into EDI. 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.
|
||
|
||
LFS (Load Pointer Using FS) operates identically to LDS except that FS
|
||
receives the segment selector rather than DS.
|
||
|
||
LGS (Load Pointer Using GS) operates identically to LDS except that GS
|
||
receives the segment selector rather than DS.
|
||
|
||
LSS (Load Pointer Using SS) operates identically to LDS except that SS
|
||
receives the segment selector rather than DS. This instruction is
|
||
especially important, because it allows the two registers that identify the
|
||
stack (SS:ESP) to be changed in one uninterruptible operation. Unlike the
|
||
other instructions which load SS, interrupts are not inhibited at the end
|
||
of the LSS instruction. The other instructions (e.g., POP SS) inhibit
|
||
interrupts to permit the following instruction to load ESP, thereby forming
|
||
an indivisible load of SS:ESP. Since both SS and ESP can be loaded by LSS,
|
||
there is no need to inhibit interrupts.
|
||
|
||
|
||
3.11 Miscellaneous Instructions
|
||
|
||
The following instructions do not fit in any of the previous categories,
|
||
but are nonetheless useful.
|
||
|
||
|
||
3.11.1 Address Calculation Instruction
|
||
|
||
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 general register.
|
||
This instruction is especially useful for initializing registers before the
|
||
execution of the string primitives (ESI, EDI) or the XLAT instruction (EBX).
|
||
The LEA can perform any indexing or scaling that may be needed.
|
||
|
||
Example: LEA EBX, EBCDIC_TABLE
|
||
|
||
Causes the processor to place the address of the starting location of the
|
||
table labeled EBCDIC_TABLE into EBX.
|
||
|
||
|
||
3.11.2 No-Operation Instruction
|
||
|
||
NOP (No Operation) occupies a byte of storage but affects nothing but the
|
||
instruction pointer, EIP.
|
||
|
||
|
||
3.11.3 Translate Instruction
|
||
|
||
XLAT (Translate) replaced 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 EBX. XLAT changes the contents of
|
||
AL from table index to table entry. EBX 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.
|
||
|
||
|
||
PART II SYSTEMS PROGRAMMING
|
||
|
||
|
||
Chapter 4 Systems Architecture
|
||
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
Many of the architectural features of the 80386 are used only by systems
|
||
programmers. This chapter presents an overview of these aspects of the
|
||
architecture.
|
||
|
||
The systems-level features of the 80386 architecture include:
|
||
|
||
Memory Management
|
||
Protection
|
||
Multitasking
|
||
Input/Output
|
||
Exceptions and Interrupts
|
||
Initialization
|
||
Coprocessing and Multiprocessing
|
||
Debugging
|
||
|
||
These features are implemented by registers and instructions, all of which
|
||
are introduced in the following sections. The purpose of this chapter is not
|
||
to explain each feature in detail, but rather to place the remaining
|
||
chapters of Part II in perspective. Each mention in this chapter of a
|
||
register or instruction is either accompanied by an explanation or a
|
||
reference to a following chapter where detailed information can be obtained.
|
||
|
||
|
||
4.1 Systems Registers
|
||
|
||
The registers designed for use by systems programmers fall into these
|
||
classes:
|
||
|
||
EFLAGS
|
||
Memory-Management Registers
|
||
Control Registers
|
||
Debug Registers
|
||
Test Registers
|
||
|
||
|
||
4.1.1 Systems Flags
|
||
|
||
The systems flags of the EFLAGS register control I/O, maskable interrupts,
|
||
debugging, task switching, and enabling of virtual 8086 execution in a
|
||
protected, multitasking environment. These flags are highlighted in Figure
|
||
4-1.
|
||
|
||
IF (Interrupt-Enable Flag, bit 9)
|
||
|
||
Setting IF allows the CPU to recognize external (maskable) interrupt
|
||
requests. Clearing IF disables these interrupts. IF has no effect on
|
||
either exceptions or nonmaskable external interrupts. Refer to Chapter
|
||
9 for more details about interrupts.
|
||
|
||
NT (Nested Task, bit 14)
|
||
|
||
The processor uses the nested task flag to control chaining of
|
||
interrupted and called tasks. NT influences the operation of the IRET
|
||
instruction. Refer to Chapter 7 and Chapter 9 for more information on
|
||
nested tasks.
|
||
|
||
RF (Resume Flag, bit 16)
|
||
|
||
The RF flag temporarily disables debug exceptions so that an instruction
|
||
can be restarted after a debug exception without immediately causing
|
||
another debug exception. Refer to Chapter 12 for details.
|
||
|
||
TF (Trap Flag, bit 8)
|
||
|
||
Setting TF puts the processor into single-step mode for debugging. In
|
||
this mode, the CPU automatically generates an exception after each
|
||
instruction, allowing a program to be inspected as it executes each
|
||
instruction. Single-stepping is just one of several debugging features of
|
||
the 80386. Refer to Chapter 12 for additional information.
|
||
|
||
VM (Virtual 8086 Mode, bit 17)
|
||
|
||
When set, the VM flag indicates that the task is executing an 8086
|
||
program. Refer to Chapter 14 for a detailed discussion of how the 80386
|
||
executes 8086 tasks in a protected, multitasking environment.
|
||
|
||
|
||
Figure 4-1. System Flags of EFLAGS Register
|
||
|
||
31 23 15 7 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÑÍÑÍÑØÑÍÑÍÍÍÍÑÍÑÍÑÍÑÍÑØÑÍÑÍÑÍÑÍÑÍÑÍÑÍ»
|
||
º±±±±±±±±±±±±±±±±±±±±±±±±±±±³V³R³±³N³ID ³O³D³I³T³S³Z³±³A³±³P³±³Cº
|
||
º0 0 0 0 0 0 0 0 0 0 0 0 0 0³ ³ ³0³ ³ ³±³±³ ³±³±³±³0³±³0³±³1³±º
|
||
º±±±±±±±±±±±±±±±±±±±±±±±±±±±³M³F³±³T³ PL³F³F³F³F³F³F³±³F³±³F³±³Fº
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÏÑÏÑÏØÏÑÏÍÑÍÍÏÍÏÍÏÑÏÍÏØÏÍÏÍÏÍÏÍÏÍÏÍÏͼ
|
||
³ ³ ³ ³ ³
|
||
VIRTUAL 8086 MODEÄÄÄÄÙ ³ ³ ³ ³
|
||
RESUME FLAGÄÄÄÄÄÄÙ ³ ³ ³
|
||
NESTED TASK FLAGÄÄÄÄÄÄÄÄÄÄÙ ³ ³
|
||
I/O PRIVILEGE LEVELÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³
|
||
INTERRUPT ENABLEÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
||
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
NOTE
|
||
0 OR 1 INDICATES INTEL RESERVED. DO NOT DEFINE.
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
|
||
4.1.2 Memory-Management Registers
|
||
|
||
Four registers of the 80386 locate the data structures that control
|
||
segmented memory management:
|
||
|
||
GDTR Global Descriptor Table Register
|
||
LDTR Local Descriptor Table Register
|
||
|
||
These registers point to the segment descriptor tables GDT and LDT.
|
||
Refer to Chapter 5 for an explanation of addressing via descriptor
|
||
tables.
|
||
|
||
IDTR Interrupt Descriptor Table Register
|
||
|
||
This register points to a table of entry points for interrupt handlers
|
||
(the IDT). Refer to Chapter 9 for details of the interrupt mechanism.
|
||
|
||
TR Task Register
|
||
|
||
This register points to the information needed by the processor to define
|
||
the current task. Refer to Chapter 7 for a description of the
|
||
multitasking features of the 80386.
|
||
|
||
|
||
4.1.3 Control Registers
|
||
|
||
Figure 4-2 shows the format of the 80386 control registers CR0, CR2, and
|
||
CR3. These registers are accessible to systems programmers only via variants
|
||
of the MOV instruction, which allow them to be loaded from or stored in
|
||
general registers; for example:
|
||
|
||
MOV EAX, CR0
|
||
MOV CR3, EBX
|
||
|
||
CR0 contains system control flags, which control or indicate conditions
|
||
that apply to the system as a whole, not to an individual task.
|
||
|
||
EM (Emulation, bit 2)
|
||
|
||
EM indicates whether coprocessor functions are to be emulated. Refer to
|
||
Chapter 11 for details.
|
||
|
||
ET (Extension Type, bit 4)
|
||
|
||
ET indicates the type of coprocessor present in the system (80287 or
|
||
80387). Refer to Chapter 11 and Chapter 10 for details.
|
||
|
||
MP (Math Present, bit 1)
|
||
|
||
MP controls the function of the WAIT instruction, which is used to
|
||
coordinate a coprocessor. Refer to Chapter 11 for details.
|
||
|
||
PE (Protection Enable, bit 0)
|
||
|
||
Setting PE causes the processor to begin executing in protected mode.
|
||
Resetting PE returns to real-address mode. Refer to Chapter 14 and
|
||
Chapter 10 for more information on changing processor modes.
|
||
|
||
PG (Paging, bit 31)
|
||
|
||
PG indicates whether the processor uses page tables to translate linear
|
||
addresses into physical addresses. Refer to Chapter 5 for a description
|
||
of page translation; refer to Chapter 10 for a discussion of how to set
|
||
PG.
|
||
|
||
TS (Task Switched, bit 3)
|
||
|
||
The processor sets TS with every task switch and tests TS when
|
||
interpreting coprocessor instructions. Refer to Chapter 11 for details.
|
||
|
||
CR2 is used for handling page faults when PG is set. The processor stores
|
||
in CR2 the linear address that triggers the fault. Refer to Chapter 9 for a
|
||
description of page-fault handling.
|
||
|
||
CR3 is used when PG is set. CR3 enables the processor to locate the page
|
||
table directory for the current task. Refer to Chapter 5 for a description
|
||
of page tables and page translation.
|
||
|
||
|
||
Figure 4-2. Control Registers
|
||
|
||
31 23 15 7 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º º º
|
||
º PAGE DIRECTORY BASE REGISTER (PDBR) º RESERVED ºCR3
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÐÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º º
|
||
º PAGE FAULT LINEAR ADDRESS ºCR2
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º º
|
||
º RESERVED ºCR1
|
||
ÇÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÂÄÂÄÂÄÂĶ
|
||
ºP³ ³E³T³E³M³Pº
|
||
ºG³ RESERVED ³T³S³M³P³EºCR0
|
||
ÈÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÏÍÏÍÏÍÏÍÏͼ
|
||
|
||
|
||
4.1.4 Debug Register
|
||
|
||
The debug registers bring advanced debugging abilities to the 80386,
|
||
including data breakpoints and the ability to set instruction breakpoints
|
||
without modifying code segments. Refer to Chapter 12 for a complete
|
||
description of formats and usage.
|
||
|
||
|
||
4.1.5 Test Registers
|
||
|
||
The test registers are not a standard part of the 80386 architecture. They
|
||
are provided solely to enable confidence testing of the translation
|
||
lookaside buffer (TLB), the cache used for storing information from page
|
||
tables. Chapter 12 explains how to use these registers.
|
||
|
||
|
||
4.2 Systems Instructions
|
||
|
||
Systems instructions deal with such functions as:
|
||
|
||
1. Verification of pointer parameters (refer to Chapter 6):
|
||
|
||
ARPL ÄÄ Adjust RPL
|
||
LAR ÄÄ Load Access Rights
|
||
LSL ÄÄ Load Segment Limit
|
||
VERR ÄÄ Verify for Reading
|
||
VERW ÄÄ Verify for Writing
|
||
|
||
2. Addressing descriptor tables (refer to Chaper 5):
|
||
|
||
LLDT ÄÄ Load LDT Register
|
||
SLDT ÄÄ Store LDT Register
|
||
LGDT ÄÄ Load GDT Register
|
||
SGDT ÄÄ Store GDT Register
|
||
|
||
3. Multitasking (refer to Chapter 7):
|
||
|
||
LTR ÄÄ Load Task Register
|
||
STR ÄÄ Store Task Register
|
||
|
||
4. Coprocessing and Multiprocessing (refer to Chapter 11):
|
||
|
||
CLTS ÄÄ Clear Task-Switched Flag
|
||
ESC ÄÄ Escape instructions
|
||
WAIT ÄÄ Wait until Coprocessor not Busy
|
||
LOCK ÄÄ Assert Bus-Lock Signal
|
||
|
||
5. Input and Output (refer to Chapter 8):
|
||
|
||
IN ÄÄ Input
|
||
OUT ÄÄ Output
|
||
INS ÄÄ Input String
|
||
OUTS ÄÄ Output String
|
||
|
||
6. Interrupt control (refer to Chapter 9):
|
||
|
||
CLI ÄÄ Clear Interrupt-Enable Flag
|
||
STI ÄÄ Set Interrupt-Enable Flag
|
||
LIDT ÄÄ Load IDT Register
|
||
SIDT ÄÄ Store IDT Register
|
||
|
||
7. Debugging (refer to Chapter 12):
|
||
|
||
MOV ÄÄ Move to and from debug registers
|
||
|
||
8. TLB testing (refer to Chapter 10):
|
||
|
||
MOV ÄÄ Move to and from test registers
|
||
|
||
9. System Control:
|
||
|
||
SMSW ÄÄ Set MSW
|
||
LMSW ÄÄ Load MSW
|
||
HLT ÄÄ Halt Processor
|
||
MOV ÄÄ Move to and from control registers
|
||
|
||
The instructions SMSW and LMSW are provided for compatibility with the
|
||
80286 processor. 80386 programs access the MSW in CR0 via variants of the
|
||
MOV instruction. HLT stops the processor until receipt of an INTR or RESET
|
||
signal.
|
||
|
||
In addition to the chapters cited above, detailed information about each of
|
||
these instructions can be found in the instruction reference chapter,
|
||
Chapter 17.
|
||
|
||
|
||
Chapter 5 Memory Management
|
||
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
The 80386 transforms logical addresses (i.e., addresses as viewed by
|
||
programmers) into physical address (i.e., actual addresses in physical
|
||
memory) in two steps:
|
||
|
||
þ Segment translation, in which a logical address (consisting of a
|
||
segment selector and segment offset) are converted to a linear address.
|
||
|
||
þ Page translation, in which a linear address is converted to a physical
|
||
address. This step is optional, at the discretion of systems-software
|
||
designers.
|
||
|
||
These translations are performed in a way that is not visible to
|
||
applications programmers. Figure 5-1 illustrates the two translations at a
|
||
high level of abstraction.
|
||
|
||
Figure 5-1 and the remainder of this chapter present a simplified view of
|
||
the 80386 addressing mechanism. In reality, the addressing mechanism also
|
||
includes memory protection features. For the sake of simplicity, however,
|
||
the subject of protection is taken up in another chapter, Chapter 6.
|
||
|
||
|
||
Figure 5-1. Address Translation Overview
|
||
|
||
15 0 31 0
|
||
LOGICAL ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
ADDRESS º SELECTOR º º OFFSET º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ ÈÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º SEGMENT TRANSLATION º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
ÉÍÍÏÍ» PAGING ENABLED
|
||
ºPG ?ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
||
ÈÍÍÑͼ ³
|
||
31 PAGING DISABLED 0 ³
|
||
LINEAR ÉÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍ» ³
|
||
ADDRESS º DIR º PAGE º OFFSET º ³
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÑÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍͼ ³
|
||
³
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» ³
|
||
º PAGE TRANSLATION º ³
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ ³
|
||
³ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
||
31 0
|
||
PHYSICAL ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
ADDRESS º º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
|
||
5.1 Segment Translation
|
||
|
||
Figure 5-2 shows in more detail how the processor converts a logical
|
||
address into a linear address.
|
||
|
||
To perform this translation, the processor uses the following data
|
||
structures:
|
||
|
||
þ Descriptors
|
||
þ Descriptor tables
|
||
þ Selectors
|
||
þ Segment Registers
|
||
|
||
|
||
5.1.1 Descriptors
|
||
|
||
The segment descriptor provides the processor with the data it needs to map
|
||
a logical address into a linear address. Descriptors are created by
|
||
compilers, linkers, loaders, or the operating system, not by applications
|
||
programmers. Figure 5-3 illustrates the two general descriptor formats. All
|
||
types of segment descriptors take one of these formats. Segment-descriptor
|
||
fields are:
|
||
|
||
BASE: Defines the location of the segment within the 4 gigabyte linear
|
||
address space. The processor concatenates the three fragments of the base
|
||
address to form a single 32-bit value.
|
||
|
||
LIMIT: Defines the size of the segment. When the processor concatenates the
|
||
two parts of the limit field, a 20-bit value results. The processor
|
||
interprets the limit field in one of two ways, depending on the setting of
|
||
the granularity bit:
|
||
|
||
1. In units of one byte, to define a limit of up to 1 megabyte.
|
||
|
||
2. In units of 4 Kilobytes, to define a limit of up to 4 gigabytes. The
|
||
limit is shifted left by 12 bits when loaded, and low-order one-bits
|
||
are inserted.
|
||
|
||
Granularity bit: Specifies the units with which the LIMIT field is
|
||
interpreted. When thebit is clear, the limit is interpreted in units of one
|
||
byte; when set, the limit is interpreted in units of 4 Kilobytes.
|
||
|
||
TYPE: Distinguishes between various kinds of descriptors.
|
||
|
||
DPL (Descriptor Privilege Level): Used by the protection mechanism (refer
|
||
to Chapter 6).
|
||
|
||
Segment-Present bit: If this bit is zero, the descriptor is not valid for
|
||
use in address transformation; the processor will signal an exception when a
|
||
selector for the descriptor is loaded into a segment register. Figure 5-4
|
||
shows the format of a descriptor when the present-bit is zero. The operating
|
||
system is free to use the locations marked AVAILABLE. Operating systems that
|
||
implement segment-based virtual memory clear the present bit in either of
|
||
these cases:
|
||
|
||
þ When the linear space spanned by the segment is not mapped by the
|
||
paging mechanism.
|
||
|
||
þ When the segment is not present in memory.
|
||
|
||
Accessed bit: The processor sets this bit when the segment is accessed;
|
||
i.e., a selector for the descriptor is loaded into a segment register or
|
||
used by a selector test instruction. Operating systems that implement
|
||
virtual memory at the segment level may, by periodically testing and
|
||
clearing this bit, monitor frequency of segment usage.
|
||
|
||
Creation and maintenance of descriptors is the responsibility of systems
|
||
software, usually requiring the cooperation of compilers, program loaders or
|
||
system builders, and therating system.
|
||
|
||
|
||
Figure 5-2. Segment Translation
|
||
|
||
15 0 31 0
|
||
LOGICAL ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
ADDRESS º SELECTOR º º OFFSET º
|
||
ÈÍÍÍÑÍÍÍÍÍÍÍÍÍÑÍͼ ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
ÚÄÄÄÄÄÄÙ ³
|
||
³ DESCRIPTOR TABLE ³
|
||
³ ÉÍÍÍÍÍÍÍÍÍÍÍÍ» ³
|
||
³ º º ³
|
||
³ º º ³
|
||
³ º º ³
|
||
³ º º ³
|
||
³ ÌÍÍÍÍÍÍÍÍÍÍÍ͹ ³
|
||
³ º SEGMENT º BASE ÉÍÍÍ» ³
|
||
Àĺ DESCRIPTOR ÇÄÄÄÄÄÄÄÄÄÄÄÄÄĺ + ºÄÄÄÄÄÄÙ
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍ͹ ADDRESS ÈÍÑͼ
|
||
º º ³
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍͼ ³
|
||
|
||
LINEAR ÉÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
ADDRESS º DIR º PAGE º OFFSET º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
|
||
Figure 5-3. General Segment-Descriptor Format
|
||
|
||
DESCRIPTORS USED FOR APPLICATIONS CODE AND DATA SEGMENTS
|
||
|
||
31 23 15 7 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÑÍÑÍÑÍÑÍÍÍÍÍÍÍÍÍØÍÑÍÍÍÍÍÑÍÑÍÍÍÍÍÑÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º ³ ³ ³ ³A³ ³ ³ ³ ³ ³ ³ º
|
||
º BASE 31..24 ³G³X³O³V³ LIMIT ³P³ DPL ³1³ TYPE³A³ BASE 23..16 º 4
|
||
º ³ ³ ³ ³L³ 19..16 ³ ³ ³ ³ ³ ³ º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÁÄÁÄÁÄÁÄÄÄÄÄÄÄÄÄÅÄÁÄÄÄÄÄÁÄÁÄÄÄÄÄÁÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º ³ º
|
||
º SEGMENT BASE 15..0 ³ SEGMENT LIMIT 15..0 º 0
|
||
º ³ º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
DESCRIPTORS USED FOR SPECIAL SYSTEM SEGMENTS
|
||
|
||
31 23 15 7 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÑÍÑÍÑÍÑÍÍÍÍÍÍÍÍÍØÍÑÍÍÍÍÍÑÍÑÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º ³ ³ ³ ³A³ ³ ³ ³ ³ ³ º
|
||
º BASE 31..24 ³G³X³O³V³ LIMIT ³P³ DPL ³0³ TYPE ³ BASE 23..16 º 4
|
||
º ³ ³ ³ ³L³ 19..16 ³ ³ ³ ³ ³ º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÁÄÁÄÁÄÁÄÄÄÄÄÄÄÄÄÅÄÁÄÄÄÄÄÁÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º ³ º
|
||
º SEGMENT BASE 15..0 ³ SEGMENT LIMIT 15..0 º 0
|
||
º ³ º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
A - ACCESSED
|
||
AVL - AVAILABLE FOR USE BY SYSTEMS PROGRAMMERS
|
||
DPL - DESCRIPTOR PRIVILEGE LEVEL
|
||
G - GRANULARITY
|
||
P - SEGMENT PRESENT
|
||
|
||
|
||
5.1.2 Descriptor Tables
|
||
|
||
Segment descriptors are stored in either of two kinds of descriptor table:
|
||
|
||
þ The global descriptor table (GDT)
|
||
þ A local descriptor table (LDT)
|
||
|
||
A descriptor table is simply a memory array of 8-byte entries that contain
|
||
descriptors, as Figure 5-5 shows. A descriptor table is variable in length
|
||
and may contain up to 8192 (2^(13)) descriptors. The first entry of the GDT
|
||
(INDEX=0) is not used by the processor, however.
|
||
|
||
The processor locates the GDT and the current LDT in memory by means of the
|
||
GDTR and LDTR registers. These registers store the base addresses of the
|
||
tables in the linear address space and store the segment limits. The
|
||
instructions LGDT and SGDT give access to the GDTR; the instructions LLDT
|
||
and SLDT give access to the LDTR.
|
||
|
||
|
||
Figure 5-4. Format of Not-Present Descriptor
|
||
|
||
31 23 15 7 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÑÍÍÍÍÍÑÍÑÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º ³ ³ ³ ³ ³ º
|
||
º AVAILABLE ³O³ DPL ³S³ TYPE ³ AVAILABLE º 4
|
||
º ³ ³ ³ ³ ³ º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÁÄÄÄÄÄÁÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º º
|
||
º AVAILABLE º 0
|
||
º º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
|
||
Figure 5-5. Descriptor Tables
|
||
|
||
GLOBAL DESCRIPTOR TABLE LOCAL DESCRIPTOR TABLE
|
||
ÉÍÍÍÍÍÍÑÍÍÍÍÍÑÍÍÍÍÍÑÍÍÍÍÍÍ» ÉÍÍÍÍÍÍÑÍÍÍÍÍÑÍÍÍÍÍÑÍÍÍÍÍÍ»
|
||
º ³ ³ ³ º º ³ ³ ³ º
|
||
ÇÄÄÄÄÄÄÁÄÄÄÄÄÅÄÄÄÄÄÁÄÄÄÄÄĶ ÇÄÄÄÄÄÄÁÄÄÄÄÄÅÄÄÄÄÄÁÄÄÄÄÄĶ
|
||
º ³ º M º ³ º M
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍͼ ÈÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
| | | |
|
||
| | | |
|
||
ÉÍÍÍÍÍÍÑÍÍÍÍÍÑÍÍÍÍÍÑÍÍÍÍÍÍ» ÉÍÍÍÍÍÍÑÍÍÍÍÍÑÍÍÍÍÍÑÍÍÍÍÍÍ»
|
||
º ³ ³ ³ º º ³ ³ ³ º
|
||
ÇÄÄÄÄÄÄÁÄÄÄÄÄÅÄÄÄÄÄÁÄÄÄÄÄĶ ÇÄÄÄÄÄÄÁÄÄÄÄÄÅÄÄÄÄÄÁÄÄÄÄÄĶ
|
||
º ³ º N + 3 º ³ º N + 3
|
||
ÌÍÍÍÍÍÍÑÍÍÍÍÍØÍÍÍÍÍÑÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÑÍÍÍÍÍØÍÍÍÍÍÑÍÍÍÍÍ͹
|
||
º ³ ³ ³ º º ³ ³ ³ º
|
||
ÇÄÄÄÄÄÄÁÄÄÄÄÄÅÄÄÄÄÄÁÄÄÄÄÄĶ ÇÄÄÄÄÄÄÁÄÄÄÄÄÅÄÄÄÄÄÁÄÄÄÄÄĶ
|
||
º ³ º N + 2 º ³ º N + 2
|
||
ÌÍÍÍÍÍÍÑÍÍÍÍÍØÍÍÍÍÍÑÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÑÍÍÍÍÍØÍÍÍÍÍÑÍÍÍÍÍ͹
|
||
º ³ ³ ³ º º ³ ³ ³ º
|
||
ÇÄÄÄÄÄÄÁÄÄÄÄÄÅÄÄÄÄÄÁÄÄÄÄÄĶ ÇÄÄÄÄÄÄÁÄÄÄÄÄÅÄÄÄÄÄÁÄÄÄÄÄĶ
|
||
º ³ º N + 1 º ³ º N + 1
|
||
ÌÍÍÍÍÍÍÑÍÍÍÍÍØÍÍÍÍÍÑÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÑÍÍÍÍÍØÍÍÍÍÍÑÍÍÍÍÍ͹
|
||
º ³ ³ ³ º º ³ ³ ³ º
|
||
ÇÄÄÄÄÄÄÁÄÄÄÄÄÅÄÄÄÄÄÁÄÄÄÄÄĶ ÇÄÄÄÄÄÄÁÄÄÄÄÄÅÄÄÄÄÄÁÄÄÄÄÄĶ
|
||
º ³ º N º ³ º N
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍͼ ÈÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
| | | |
|
||
| | | |
|
||
ÉÍÍÍÍÍÍÑÍÍÍÍÍÑÍÍÍÍÍÑÍÍÍÍÍÍ» ÉÍÍÍÍÍÍÑÍÍÍÍÍÑÍÍÍÍÍÑÍÍÍÍÍÍ»
|
||
º ³ ³ ³ º º ³ ³ ³ º
|
||
ÇÄÄÄÄÄÄÁÄÄ(UNUSED)ÄÁÄÄÄÄÄĶ ÇÄÄÄÄÄÄÁÄÄÄÄÄÅÄÄÄÄÄÁÄÄÄÄÄĶ
|
||
º ³ º º ³ º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍͼ ÈÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» ³ ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» ³
|
||
º GDTR ÇÄÄÙ º LDTR ÇÄÄÙ
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
|
||
5.1.3 Selectors
|
||
|
||
The selector portion of a logical address identifies a descriptor by
|
||
specifying a descriptor table and indexing a descriptor within that table.
|
||
Selectors may be visible to applications programs as a field within a
|
||
pointer variable, but the values of selectors are usually assigned (fixed
|
||
up) by linkers or linking loaders. Figure 5-6 shows the format of a
|
||
selector.
|
||
|
||
Index: Selects one of 8192 descriptors in a descriptor 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.
|
||
|
||
Table Indicator: Specifies to which descriptor table the selector refers. A
|
||
zero indicates the GDT; a one indicates the current LDT.
|
||
|
||
Requested Privilege Level: Used by the protection mechanism. (Refer to
|
||
Chapter 6.)
|
||
|
||
Because the first entry of the GDT is not used by the processor, a selector
|
||
that has an index of zero and a table indicator of zero (i.e., a selector
|
||
that points to the first entry of the GDT), can be used as a null selector.
|
||
The processor does not cause an exception when a segment register (other
|
||
than CS or SS) is loaded with a null selector. It will, however, cause an
|
||
exception when the segment register is used to access memory. This feature
|
||
is useful for initializing unused segment registers so as to trap accidental
|
||
references.
|
||
|
||
|
||
Figure 5-6. Format of a Selector
|
||
|
||
15 4 3 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÑÍÍÍ»
|
||
º ³T³ º
|
||
º INDEX ³ ³RPLº
|
||
º ³I³ º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÏÍÍͼ
|
||
|
||
TI - TABLE INDICATOR
|
||
RPL - REQUESTOR'S PRIVILEGE LEVEL
|
||
|
||
|
||
Figure 5-7. Segment Registers
|
||
|
||
16-BIT VISIBLE
|
||
SELECTOR HIDDEN DESCRIPTOR
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
CS º º º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
SS º º º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
DS º º º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
ES º º º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
FS º º º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
GS º º º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
|
||
5.1.4 Segment Registers
|
||
|
||
The 80386 stores information from descriptors in segment registers, thereby
|
||
avoiding the need to consult a descriptor table every time it accesses
|
||
memory.
|
||
|
||
Every segment register has a "visible" portion and an "invisible" portion,
|
||
as Figure 5-7 illustrates. The visible portions of these segment address
|
||
registers are manipulated by programs as if they were simply 16-bit
|
||
registers. The invisible portions are manipulated by the processor.
|
||
|
||
The operations that load these registers are normal program instructions
|
||
(previously described in Chapter 3). These instructions are of two classes:
|
||
|
||
1. Direct load instructions; for example, MOV, POP, LDS, LSS, LGS, LFS.
|
||
These instructions explicitly reference the segment registers.
|
||
|
||
2. Implied load instructions; for example, far CALL and JMP. These
|
||
instructions implicitly reference the CS register, and load it with a
|
||
new value.
|
||
|
||
Using these instructions, a program loads the visible part of the segment
|
||
register with a 16-bit selector. The processor automatically fetches the
|
||
base address, limit, type, and other information from a descriptor table and
|
||
loads them into the invisible part of the segment register.
|
||
|
||
Because most instructions refer to data in segments whose selectors have
|
||
already been loaded into segment registers, the processor can add the
|
||
segment-relative offset supplied by the instruction to the segment base
|
||
address with no additional overhead.
|
||
|
||
|
||
5.2 Page Translation
|
||
|
||
In the second phase of address transformation, the 80386 transforms a
|
||
linear address into a physical address. This phase of address transformation
|
||
implements the basic features needed for page-oriented virtual-memory
|
||
systems and page-level protection.
|
||
|
||
The page-translation step is optional. Page translation is in effect only
|
||
when the PG bit of CR0 is set. This bit is typically set by the operating
|
||
system during software initialization. The PG bit must be set if the
|
||
operating system is to implement multiple virtual 8086 tasks, page-oriented
|
||
protection, or page-oriented virtual memory.
|
||
|
||
|
||
5.2.1 Page Frame
|
||
|
||
A page frame is a 4K-byte unit of contiguous addresses of physical memory.
|
||
Pages begin onbyte boundaries and are fixed in size.
|
||
|
||
|
||
5.2.2 Linear Address
|
||
|
||
A linear address refers indirectly to a physical address by specifying a
|
||
page table, a page within that table, and an offset within that page. Figure
|
||
5-8 shows the format of a linear address.
|
||
|
||
Figure 5-9 shows how the processor converts the DIR, PAGE, and OFFSET
|
||
fields of a linear address into the physical address by consulting two
|
||
levels of page tables. The addressing mechanism uses the DIR field as an
|
||
index into a page directory, uses the PAGE field as an index into the page
|
||
table determined by the page directory, and uses the OFFSET field to address
|
||
a byte within the page determined by the page table.
|
||
|
||
|
||
Figure 5-8. Format of a Linear Address
|
||
|
||
31 22 21 12 11 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º º º º
|
||
º DIR º PAGE º OFFSET º
|
||
º º º º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
|
||
Figure 5-9. Page Translation
|
||
|
||
PAGE FRAME
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍ» ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º DIR º PAGE º OFFSET º º º
|
||
ÈÍÍÍÍÍÑÍÍÍÍÍÊÍÍÍÍÍÑÍÍÍÍÍÊÍÍÍÍÍÑÍÍÍͼ º º
|
||
³ ³ ³ º º
|
||
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄĺ PHYSICAL º
|
||
³ ³ º ADDRESS º
|
||
³ PAGE DIRECTORY ³ PAGE TABLE º º
|
||
³ ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» ³ ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» º º
|
||
³ º º ³ º º ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
³ º º ³ ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
³ º º ÀÄĺ PG TBL ENTRY ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
||
³ ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
Àĺ DIR ENTRY ÇÄÄ¿ º º
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ ³ º º
|
||
º º ³ º º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ ³ ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
³
|
||
ÉÍÍÍÍÍÍÍ» ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
||
º CR3 ÇÄÄÄÄÄÄÄÄÙ
|
||
ÈÍÍÍÍÍÍͼ
|
||
|
||
|
||
5.2.3 Page Tables
|
||
|
||
A page table is simply an array of 32-bit page specifiers. A page table is
|
||
itself a page, and therefore contains 4 Kilobytes of memory or at most 1K
|
||
32-bit entries.
|
||
|
||
Two levels of tables are used to address a page of memory. At the higher
|
||
level is a page directory. The page directory addresses up to 1K page tables
|
||
of the second level. A page table of the second level addresses up to 1K
|
||
pages. All the tables addressed by one page directory, therefore, can
|
||
address 1M pages (2^(20)). Because each page contains 4K bytes 2^(12)
|
||
bytes), the tables of one page directory can span the entire physical
|
||
address space of the 80386 (2^(20) times 2^(12) = 2^(32)).
|
||
|
||
The physical address of the current page directory is stored in the CPU
|
||
register CR3, also called the page directory base register (PDBR). Memory
|
||
management software has the option of using one page directory for all
|
||
tasks, one page directory for each task, or some combination of the two.
|
||
Refer to Chapter 10 for information on initialization of CR3. Refer to
|
||
Chapter 7 to see how CR3 can change for each task.
|
||
|
||
|
||
5.2.4 Page-Table Entries
|
||
|
||
Entries in either level of page tables have the same format. Figure 5-10
|
||
illustrates this format.
|
||
|
||
|
||
5.2.4.1 Page Frame Address
|
||
|
||
The page frame address specifies the physical starting address of a page.
|
||
Because pages are located on 4K boundaries, the low-order 12 bits are always
|
||
zero. In a page directory, the page frame address is the address of a page
|
||
table. In a second-level page table, the page frame address is the address
|
||
of the page frame that contains the desired memory operand.
|
||
|
||
|
||
5.2.4.2 Present Bit
|
||
|
||
The Present bit indicates whether a page table entry can be used in address
|
||
translation. P=1 indicates that the entry can be used.
|
||
|
||
When P=0 in either level of page tables, the entry is not valid for address
|
||
translation, and the rest of the entry is available for software use; none
|
||
of the other bits in the entry is tested by the hardware. Figure 5-11
|
||
illustrates the format of a page-table entry when P=0.
|
||
|
||
If P=0 in either level of page tables when an attempt is made to use a
|
||
page-table entry for address translation, the processor signals a page
|
||
exception. In software systems that support paged virtual memory, the
|
||
page-not-present exception handler can bring the required page into physical
|
||
memory. The instruction that caused the exception can then be reexecuted.
|
||
Refer to Chapter 9 for more information on exception handlers.
|
||
|
||
Note that there is no present bit for the page directory itself. The page
|
||
directory may be not-present while the associated task is suspended, but the
|
||
operating system must ensure that the page directory indicated by the CR3
|
||
image in the TSS is present in physical memory before the task is
|
||
dispatched. Refer to Chapter 7 for an explanation of the TSS and task
|
||
dispatching.
|
||
|
||
|
||
Figure 5-10. Format of a Page Table Entry
|
||
|
||
31 12 11 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÑÍÍÍÑÍÑÍÑÍÍÍÑÍÑÍÑÍ»
|
||
º ³ ³ ³ ³ ³ ³U³R³ º
|
||
º PAGE FRAME ADDRESS 31..12 ³ AVAIL ³0 0³D³A³0 0³/³/³Pº
|
||
º ³ ³ ³ ³ ³ ³S³W³ º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÏÍÍÍÏÍÏÍÏÍÍÍÏÍÏÍÏͼ
|
||
|
||
P - PRESENT
|
||
R/W - READ/WRITE
|
||
U/S - USER/SUPERVISOR
|
||
D - DIRTY
|
||
AVAIL - AVAILABLE FOR SYSTEMS PROGRAMMER USE
|
||
|
||
NOTE: 0 INDICATES INTEL RESERVED. DO NOT DEFINE.
|
||
|
||
|
||
Figure 5-11. Invalid Page Table Entry
|
||
|
||
31 1 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍ»
|
||
º ³ º
|
||
º AVAILABLE ³0º
|
||
º ³ º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏͼ
|
||
|
||
|
||
5.2.4.3 Accessed and Dirty Bits
|
||
|
||
These bits provide data about page usage in both levels of the page tables.
|
||
With the exception of the dirty bit in a page directory entry, these bits
|
||
are set by the hardware; however, the processor does not clear any of these
|
||
bits.
|
||
|
||
The processor sets the corresponding accessed bits in both levels of page
|
||
tables to one before a read or write operation to a page.
|
||
|
||
The processor sets the dirty bit in the second-level page table to one
|
||
before a write to an address covered by that page table entry. The dirty bit
|
||
in directory entries is undefined.
|
||
|
||
An operating system that supports paged virtual memory can use these bits
|
||
to determine what pages to eliminate from physical memory when the demand
|
||
for memory exceeds the physical memory available. The operating system is
|
||
responsible for testing and clearing these bits.
|
||
|
||
Refer to Chapter 11 for how the 80386 coordinates updates to the accessed
|
||
and dirty bits in multiprocessor systems.
|
||
|
||
|
||
5.2.4.4 Read/Write and User/Supervisor Bits
|
||
|
||
These bits are not used for address translation, but are used for
|
||
page-level protection, which the processor performs at the same time as
|
||
address translation. Refer to Chapter 6 where protection is discussed in
|
||
detail.
|
||
|
||
|
||
5.2.5 Page Translation Cache
|
||
|
||
For greatest efficiency in address translation, the processor stores the
|
||
most recently used page-table data in an on-chip cache. Only if the
|
||
necessary paging information is not in the cache must both levels of page
|
||
tables be referenced.
|
||
|
||
The existence of the page-translation cache is invisible to applications
|
||
programmers but not to systems programmers; operating-system programmers
|
||
must flush the cache whenever the page tables are changed. The
|
||
page-translation cache can be flushed by either of two methods:
|
||
|
||
1. By reloading CR3 with a MOV instruction; for example:
|
||
|
||
MOV CR3, EAX
|
||
|
||
2. By performing a task switch to a TSS that has a different CR3 image
|
||
than the current TSS. (Refer to Chapter 7 for more information on
|
||
task switching.)
|
||
|
||
|
||
5.3 Combining Segment and Page Translation
|
||
|
||
Figure 5-12 combines Figure 5-2 and Figure 5-9 to summarize both phases
|
||
of the transformation from a logical address to a physical address when
|
||
paging is enabled. By appropriate choice of options and parameters to both
|
||
phases, memory-management software can implement several different styles of
|
||
memory management.
|
||
|
||
|
||
5.3.1 "Flat" Architecture
|
||
|
||
When the 80386 is used to execute software designed for architectures that
|
||
don't have segments, it may be expedient to effectively "turn off" the
|
||
segmentation features of the 80386. The 80386 does not have a mode that
|
||
disables segmentation, but the same effect can be achieved by initially
|
||
loading the segment registers with selectors for descriptors that encompass
|
||
the entire 32-bit linear address space. Once loaded, the segment registers
|
||
don't need to be changed. The 32-bit offsets used by 80386 instructions are
|
||
adequate to address the entire linear-address space.
|
||
|
||
|
||
5.3.2 Segments Spanning Several Pages
|
||
|
||
The architecture of the 80386 permits segments to be larger or smaller than
|
||
the size of a page (4 Kilobytes). For example, suppose a segment is used to
|
||
address and protect a large data structure that spans 132 Kilobytes. In a
|
||
software system that supports paged virtual memory, it is not necessary for
|
||
the entire structure to be in physical memory at once. The structure is
|
||
divided into 33 pages, any number of which may not be present. The
|
||
applications programmer does not need to be aware that the virtual memory
|
||
subsystem is paging the structure in this manner.
|
||
|
||
|
||
Figure 5-12. 80306 Addressing Machanism
|
||
|
||
16 0 32 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» LOGICAL
|
||
º SELECTOR º OFFSET º ADDRESS
|
||
ÈÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
ÚÄÄÄÄÄÄÄÙ ³
|
||
³ DESCRIPTOR TABLE ³
|
||
³ ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» ³
|
||
³ º º ³
|
||
³ º º ³
|
||
³ º º ³
|
||
³ º º ³
|
||
³ ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ ³
|
||
³ º SEGMENT º ÉÍÍÍ» ³
|
||
Àĺ DESCRIPTOR ÇÄÄÄÄÄÄÄĺ + ºÄÄÄÄÄÄÄÄÄÄÙ
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ ÈÍÑͼ
|
||
º º ³
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ ³
|
||
PAGE FRAME
|
||
LINEAR ÉÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍ» ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
ADDRESS º DIR º PAGE º OFFSET º º º
|
||
ÈÍÍÍÍÍÑÍÍÍÍÍÊÍÍÍÍÍÑÍÍÍÍÍÊÍÍÍÍÍÑÍÍÍͼ º º
|
||
³ ³ ³ º º
|
||
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄĺ PHYSICAL º
|
||
³ ³ º ADDRESS º
|
||
³ PAGE DIRECTORY ³ PAGE TABLE º º
|
||
³ ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» ³ ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» º º
|
||
³ º º ³ º º º º
|
||
³ º º ³ º º ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
³ º º ³ ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
³ º º ÀÄĺ PG TBL ENTRY ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
||
³ ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
Àĺ DIR ENTRY ÇÄÄ¿ º º
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ ³ º º
|
||
º º ³ º º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ ³ ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
³
|
||
ÉÍÍÍÍÍÍÍ» ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
||
º CR3 ÇÄÄÄÄÄÄÄÄÙ
|
||
ÈÍÍÍÍÍÍͼ
|
||
|
||
|
||
5.3.3 Pages Spanning Several Segments
|
||
|
||
On the other hand, segments may be smaller than the size of a page. For
|
||
example, consider a small data structure such as a semaphore. Because of the
|
||
protection and sharing provided by segments (refer to Chapter 6), it may be
|
||
useful to create a separate segment for each semaphore. But, because a
|
||
system may need many semaphores, it is not efficient to allocate a page for
|
||
each. Therefore, it may be useful to cluster many related segments within a
|
||
page.
|
||
|
||
|
||
5.3.4 Non-Aligned Page and Segment Boundaries
|
||
|
||
The architecture of the 80386 does not enforce any correspondence between
|
||
the boundaries of pages and segments. It is perfectly permissible for a page
|
||
to contain the end of one segment and the beginning of another. Likewise, a
|
||
segment may contain the end of one page and the beginning of another.
|
||
|
||
|
||
5.3.5 Aligned Page and Segment Boundaries
|
||
|
||
Memory-management software may be simpler, however, if it enforces some
|
||
correspondence between page and segment boundaries. For example, if segments
|
||
are allocated only in units of one page, the logic for segment and page
|
||
allocation can be combined. There is no need for logic to account for
|
||
partially used pages.
|
||
|
||
|
||
5.3.6 Page-Table per Segment
|
||
|
||
An approach to space management that provides even further simplification
|
||
of space-management software is to maintain a one-to-one correspondence
|
||
between segment descriptors and page-directory entries, as Figure 5-13
|
||
illustrates. Each descriptor has a base address in which the low-order 22
|
||
bits are zero; in other words, the base address is mapped by the first entry
|
||
of a page table. A segment may have any limit from 1 to 4 megabytes.
|
||
Depending on the limit, the segment is contained in from 1 to 1K page
|
||
frames. A task is thus limited to 1K segments (a sufficient number for many
|
||
applications), each containing up to 4 Mbytes. The descriptor, the
|
||
corresponding page-directory entry, and the corresponding page table can be
|
||
allocated and deallocated simultaneously.
|
||
|
||
|
||
Figure 5-13. Descriptor per Page Table
|
||
|
||
PAGE FRAMES
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍ»
|
||
LDT PAGE DIRECTORY PAGE TABLES º º
|
||
ÉÍÍÍÍÍÍÍÍÍÍ» ÉÍÍÍÍÍÍÍÍÍÍ» ÉÍÍÍÍÍÍÍÍÍÍ» º º
|
||
º º º º º º ÚÄÈÍÍÍÍÍÍÍÍÍÍͼ
|
||
ÌÍÍÍÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍÍÍ͹ ³
|
||
º º º º º PTE ÇÄÄÄÙ ÉÍÍÍÍÍÍÍÍÍÍÍ»
|
||
ÌÍÍÍÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍÍÍ͹ º º
|
||
º º º º º PTE ÇÄÄÄ¿ º º
|
||
ÌÍÍÍÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍÍÍ͹ ÀÄÈÍÍÍÍÍÍÍÍÍÍͼ
|
||
º º º º º PTE ÇÄÄÄ¿
|
||
ÌÍÍÍÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍÍÍ͹ ÚÄÄÄÈÍÍÍÍÍÍÍÍÍͼ ³ ÉÍÍÍÍÍÍÍÍÍÍÍ»
|
||
ºDESCRIPTORÇÄÄÄÄÄĺ PDE ÇÄÄÄÙ ³ º º
|
||
ÌÍÍÍÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍÍÍ͹ ³ º º
|
||
ºDESCRIPTORÇÄÄÄÄÄĺ PDE ÇÄÄÄ¿ ÀÄÈÍÍÍÍÍÍÍÍÍÍͼ
|
||
ÌÍÍÍÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍÍÍ͹ ³ ÉÍÍÍÍÍÍÍÍÍÍ»
|
||
º º º º ³ º º ÉÍÍÍÍÍÍÍÍÍÍÍ»
|
||
ÌÍÍÍÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍÍÍ͹ ³ ÌÍÍÍÍÍÍÍÍÍ͹ º º
|
||
º º º º ³ º º º º
|
||
ÌÍÍÍÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍÍÍ͹ ³ ÌÍÍÍÍÍÍÍÍÍ͹ ÚÄÈÍÍÍÍÍÍÍÍÍÍͼ
|
||
º º º º ³ º PTE ÇÄÄÄÙ
|
||
ÌÍÍÍÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍÍÍ͹ ³ ÌÍÍÍÍÍÍÍÍÍ͹ ÉÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º º º º ³ º PTE ÇÄÄÄ¿ º º
|
||
ÈÍÍÍÍÍÍÍÍÍͼ ÈÍÍÍÍÍÍÍÍÍͼ ÀÄÄÄÈÍÍÍÍÍÍÍÍÍͼ ³ º º
|
||
LDT PAGE DIRECTORY PAGE TABLES ÀÄÈÍÍÍÍÍÍÍÍÍÍͼ
|
||
PAGE FRAMES
|
||
|
||
|
||
Chapter 6 Protection
|
||
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
6.1 Why Protection?
|
||
|
||
The purpose of the protection features of the 80386 is to help detect and
|
||
identify bugs. The 80386 supports sophisticated applications that may
|
||
consist of hundreds or thousands of program modules. In such applications,
|
||
the question is how bugs can be found and eliminated as quickly as possible
|
||
and how their damage can be tightly confined. To help debug applications
|
||
faster and make them more robust in production, the 80386 contains
|
||
mechanisms to verify memory accesses and instruction execution for
|
||
conformance to protection criteria. These mechanisms may be used or ignored,
|
||
according to system design objectives.
|
||
|
||
|
||
6.2 Overview of 80386 Protection Mechanisms
|
||
|
||
Protection in the 80386 has five aspects:
|
||
|
||
1. Type checking
|
||
2. Limit checking
|
||
3. Restriction of addressable domain
|
||
4. Restriction of procedure entry points
|
||
5. Restriction of instruction set
|
||
|
||
The protection hardware of the 80386 is an integral part of the memory
|
||
management hardware. Protection applies both to segment translation and to
|
||
page translation.
|
||
|
||
Each reference to memory is checked by the hardware to verify that it
|
||
satisfies the protection criteria. All these checks are made before the
|
||
memory cycle is started; any violation prevents that cycle from starting and
|
||
results in an exception. Since the checks are performed concurrently with
|
||
address formation, there is no performance penalty.
|
||
|
||
Invalid attempts to access memory result in an exception. Refer to
|
||
Chapter 9 for an explanation of the exception mechanism. The present
|
||
chapter defines the protection violations that lead to exceptions.
|
||
|
||
The concept of "privilege" is central to several aspects of protection
|
||
(numbers 3, 4, and 5 in the preceeding list). Applied to procedures,
|
||
privilege is the degree to which the procedure can be trusted not to make a
|
||
mistake that might affect other procedures or data. Applied to data,
|
||
privilege is the degree of protection that a data structure should have
|
||
from less trusted procedures.
|
||
|
||
The concept of privilege applies both to segment protection and to page
|
||
protection.
|
||
|
||
|
||
6.3 Segment-Level Protection
|
||
|
||
All five aspects of protection apply to segment translation:
|
||
|
||
1. Type checking
|
||
2. Limit checking
|
||
3. Restriction of addressable domain
|
||
4. Restriction of procedure entry points
|
||
5. Restriction of instruction set
|
||
|
||
The segment is the unit of protection, and segment descriptors store
|
||
protection parameters. Protection checks are performed automatically by the
|
||
CPU when the selector of a segment descriptor is loaded into a segment
|
||
register and with every segment access. Segment registers hold the
|
||
protection parameters of the currently addressable segments.
|
||
|
||
|
||
6.3.1 Descriptors Store Protection Parameters
|
||
|
||
Figure 6-1 highlights the protection-related fields of segment descriptors.
|
||
|
||
The protection parameters are placed in the descriptor by systems software
|
||
at the time a descriptor is created. In general, applications programmers do
|
||
not need to be concerned about protection parameters.
|
||
|
||
When a program loads a selector into a segment register, the processor
|
||
loads not only the base address of the segment but also protection
|
||
information. Each segment register has bits in the invisible portion for
|
||
storing base, limit, type, and privilege level; therefore, subsequent
|
||
protection checks on the same segment do not consume additional clock
|
||
cycles.
|
||
|
||
|
||
Figure 6-1. Protection Fields of Segment Descriptors
|
||
|
||
DATA SEGMENT DESCRIPTOR
|
||
|
||
31 23 15 7 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÑÍÑÍÑÍÑÍÍÍÍÍÍÍÍÍØÍÑÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º±±±±±±±±±±±±±±±±±³±³±³±³A³ LIMIT ³±³ ³ TYPE ³±±±±±±±±±±±±±±±±±º
|
||
º±±±BASE 31..24±±±³G³B³0³V³ 19..16 ³P³ DPL ³ ³±±±BASE 23..16±±±º 4
|
||
º±±±±±±±±±±±±±±±±±³±³±³±³L³ ³±³ ³1³0³E³W³A³±±±±±±±±±±±±±±±±±º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÁÄÁÄÁÄÁÄÄÄÄÄÄÄÄÄÅÄÁÄÄÄÄÄÁÄÁÄÁÄÁÄÁÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±³ º
|
||
º±±±±±±±±SEGMENT BASE 15..0±±±±±±±±±³ SEGMENT LIMIT 15..0 º 0
|
||
º±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±³ º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
EXECUTABLE SEGMENT DESCRIPTOR
|
||
|
||
31 23 15 7 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÑÍÑÍÑÍÑÍÍÍÍÍÍÍÍÍØÍÑÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º±±±±±±±±±±±±±±±±±³±³±³±³A³ LIMIT ³±³ ³ TYPE ³±±±±±±±±±±±±±±±±±º
|
||
º±±±BASE 31..24±±±³G³D³0³V³ 19..16 ³P³ DPL ³ ³±±±BASE 23..16±±±º 4
|
||
º±±±±±±±±±±±±±±±±±³±³±³±³L³ ³±³ ³1³0³C³R³A³±±±±±±±±±±±±±±±±±º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÁÄÁÄÁÄÁÄÄÄÄÄÄÄÄÄÅÄÁÄÄÄÄÄÁÄÁÄÁÄÁÄÁÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±³ º
|
||
º±±±±±±±±SEGMENT BASE 15..0±±±±±±±±±³ SEGMENT LIMIT 15..0 º 0
|
||
º±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±³ º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
SYSTEM SEGMENT DESCRIPTOR
|
||
|
||
31 23 15 7 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÑÍÑÍÑÍÑÍÍÍÍÍÍÍÍÍØÍÑÍÍÍÍÍÑÍÑÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º±±±±±±±±±±±±±±±±±³±³±³±³A³ LIMIT ³±³ ³ ³ ³±±±±±±±±±±±±±±±±±º
|
||
º±±±BASE 31..24±±±³G³X³0³V³ 19..16 ³P³ DPL ³0³ TYPE ³±±±BASE 23..16±±±º 4
|
||
º±±±±±±±±±±±±±±±±±³±³±³±³L³ ³±³ ³ ³ ³±±±±±±±±±±±±±±±±±º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÁÄÁÄÁÄÁÄÄÄÄÄÄÄÄÄÅÄÁÄÄÄÄÄÁÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±³ º
|
||
º±±±±±±±±SEGMENT BASE 15..0±±±±±±±±±³ SEGMENT LIMIT 15..0 º 0
|
||
º±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±³ º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
|
||
A - ACCESSED E - EXPAND-DOWN
|
||
AVL - AVAILABLE FOR PROGRAMMERS USE G - GRANULARITY
|
||
B - BIG P - SEGMENT PRESENT
|
||
C - CONFORMING R - READABLE
|
||
D - DEFAULT W - WRITABLE
|
||
DPL - DESCRIPTOR PRIVILEGE LEVEL
|
||
|
||
|
||
6.3.1.1 Type Checking
|
||
|
||
The TYPE field of a descriptor has two functions:
|
||
|
||
1. It distinguishes among different descriptor formats.
|
||
2. It specifies the intended usage of a segment.
|
||
|
||
Besides the descriptors for data and executable segments commonly used by
|
||
applications programs, the 80386 has descriptors for special segments used
|
||
by the operating system and for gates. Table 6-1 lists all the types defined
|
||
for system segments and gates. Note that not all descriptors define
|
||
segments; gate descriptors have a different purpose that is discussed later
|
||
in this chapter.
|
||
|
||
The type fields of data and executable segment descriptors include bits
|
||
which further define the purpose of the segment (refer to Figure 6-1):
|
||
|
||
þ The writable bit in a data-segment descriptor specifies whether
|
||
instructions can write into the segment.
|
||
|
||
þ The readable bit in an executable-segment descriptor specifies
|
||
whether instructions are allowed to read from the segment (for example,
|
||
to access constants that are stored with instructions). A readable,
|
||
executable segment may be read in two ways:
|
||
|
||
1. Via the CS register, by using a CS override prefix.
|
||
|
||
2. By loading a selector of the descriptor into a data-segment register
|
||
(DS, ES, FS,or GS).
|
||
|
||
Type checking can be used to detect programming errors that would attempt
|
||
to use segments in ways not intended by the programmer. The processor
|
||
examines type information on two kinds of occasions:
|
||
|
||
1. When a selector of a descriptor is loaded into a segment register.
|
||
Certain segment registers can contain only certain descriptor types;
|
||
for example:
|
||
|
||
þ The CS register can be loaded only with a selector of an executable
|
||
segment.
|
||
|
||
þ Selectors of executable segments that are not readable cannot be
|
||
loaded into data-segment registers.
|
||
|
||
þ Only selectors of writable data segments can be loaded into SS.
|
||
|
||
2. When an instruction refers (implicitly or explicitly) to a segment
|
||
register. Certain segments can be used by instructions only in certain
|
||
predefined ways; for example:
|
||
|
||
þ No instruction may write into an executable segment.
|
||
|
||
þ No instruction may write into a data segment if the writable bit is
|
||
not set.
|
||
|
||
þ No instruction may read an executable segment unless the readable bit
|
||
is set.
|
||
|
||
|
||
Table 6-1. System and Gate Descriptor Types
|
||
|
||
Code Type of Segment or Gate
|
||
|
||
0 -reserved
|
||
1 Available 286 TSS
|
||
2 LDT
|
||
3 Busy 286 TSS
|
||
4 Call Gate
|
||
5 Task Gate
|
||
6 286 Interrupt Gate
|
||
7 286 Trap Gate
|
||
8 -reserved
|
||
9 Available 386 TSS
|
||
A -reserved
|
||
B Busy 386 TSS
|
||
C 386 Call Gate
|
||
D -reserved
|
||
E 386 Interrupt Gate
|
||
F 386 Trap Gate
|
||
|
||
|
||
6.3.1.2 Limit Checking
|
||
|
||
The limit field of a segment descriptor is used by the processor to prevent
|
||
programs from addressing outside the segment. The processor's interpretation
|
||
of the limit depends on the setting of the G (granularity) bit. For data
|
||
segments, the processor's interpretation of the limit depends also on the
|
||
E-bit (expansion-direction bit) and the B-bit (big bit) (refer to Table
|
||
6-2).
|
||
|
||
When G=0, the actual limit is the value of the 20-bit limit field as it
|
||
appears in the descriptor. In this case, the limit may range from 0 to
|
||
0FFFFFH (2^(20) - 1 or 1 megabyte). When G=1, the processor appends 12
|
||
low-order one-bits to the value in the limit field. In this case the actual
|
||
limit may range from 0FFFH (2^(12) - 1 or 4 kilobytes) to 0FFFFFFFFH(2^(32)
|
||
- 1 or 4 gigabytes).
|
||
|
||
For all types of segments except expand-down data segments, the value of
|
||
the limit is one less than the size (expressed in bytes) of the segment. The
|
||
processor causes a general-protection exception in any of these cases:
|
||
|
||
þ Attempt to access a memory byte at an address > limit.
|
||
þ Attempt to access a memory word at an address òlimit.
|
||
þ Attempt to access a memory doubleword at an address ò(limit-2).
|
||
|
||
For expand-down data segments, the limit has the same function but is
|
||
interpreted differently. In these cases the range of valid addresses is from
|
||
limit + 1 to either 64K or 2^(32) - 1 (4 Gbytes) depending on the B-bit. An
|
||
expand-down segment has maximum size when the limit is zero.
|
||
|
||
The expand-down feature makes it possible to expand the size of a stack by
|
||
copying it to a larger segment without needing also to update intrastack
|
||
pointers.
|
||
|
||
The limit field of descriptors for descriptor tables is used by the
|
||
processor to prevent programs from selecting a table entry outside the
|
||
descriptor table. The limit of a descriptor table identifies the last valid
|
||
byte of the last descriptor in the table. Since each descriptor is eight
|
||
bytes long, the limit value is N * 8 - 1 for a table that can contain up to
|
||
N descriptors.
|
||
|
||
Limit checking catches programming errors such as runaway subscripts and
|
||
invalid pointer calculations. Such errors are detected when they occur, so
|
||
that identification of the cause is easier. Without limit checking, such
|
||
errors could corrupt other modules; the existence of such errors would not
|
||
be discovered until later, when the corrupted module behaves incorrectly,
|
||
and when identification of the cause is difficult.
|
||
|
||
|
||
Table 6-2. Useful Combinations of E, G, and B Bits
|
||
|
||
|
||
Case: 1 2 3 4
|
||
|
||
Expansion Direction U U D D
|
||
G-bit 0 1 0 1
|
||
B-bit X X 0 1
|
||
|
||
Lower bound is:
|
||
0 X X
|
||
LIMIT+1 X
|
||
shl(LIMIT,12,1)+1 X
|
||
|
||
Upper bound is:
|
||
LIMIT X
|
||
shl(LIMIT,12,1) X
|
||
64K-1 X
|
||
4G-1 X
|
||
|
||
Max seg size is:
|
||
64K X
|
||
64K-1 X
|
||
4G-4K X
|
||
4G X
|
||
|
||
Min seg size is:
|
||
0 X X
|
||
4K X X
|
||
|
||
shl (X, 12, 1) = shift X left by 12 bits inserting one-bits on the right
|
||
|
||
|
||
6.3.1.3 Privilege Levels
|
||
|
||
The concept of privilege is implemented by assigning a value from zero to
|
||
three to key objects recognized by the processor. This value is called the
|
||
privilege level. The value zero represents the greatest privilege, the
|
||
value three represents the least privilege. The following
|
||
processor-recognized objects contain privilege levels:
|
||
|
||
þ Descriptors contain a field called the descriptor privilege level
|
||
(DPL).
|
||
|
||
þ Selectors contain a field called the requestor's privilege level
|
||
(RPL). The RPL is intended to represent the privilege level of
|
||
the procedure that originates a selector.
|
||
|
||
þ An internal processor register records the current privilege level
|
||
(CPL). Normally the CPL is equal to the DPL of the segment that
|
||
the processor is currently executing. CPL changes as control is
|
||
transferred to segments with differing DPLs.
|
||
|
||
The processor automatically evaluates the right of a procedure to access
|
||
another segment by comparing the CPL to one or more other privilege levels.
|
||
The evaluation is performed at the time the selector of a descriptor is
|
||
loaded into a segment register. The criteria used for evaluating access to
|
||
data differs from that for evaluating transfers of control to executable
|
||
segments; therefore, the two types of access are considered separately in
|
||
the following sections.
|
||
|
||
Figure 6-2 shows how these levels of privilege can be interpreted as rings
|
||
of protection. The center is for the segments containing the most critical
|
||
software, usually the kernel of the operating system. Outer rings are for
|
||
the segments of less critical software.
|
||
|
||
It is not necessary to use all four privilege levels. Existing software
|
||
that was designed to use only one or two levels of privilege can simply
|
||
ignore the other levels offered by the 80386. A one-level system should use
|
||
privilege level zero; a two-level system should use privilege levels zero
|
||
and three.
|
||
|
||
|
||
Figure 6-2. Levels of Privilege
|
||
|
||
TASK C
|
||
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
||
³ ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» ³
|
||
³ º APPLICATIONS º ³
|
||
³ º ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» º ³
|
||
³ º º CUSTOM EXTENSIONS º º ³
|
||
³ º º ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» º º ³
|
||
³ º º º SYSTEM SERVICES º º º ³
|
||
³ º º º ÉÍÍÍÍÍÍÍÍÍÍÍ» º º º ³
|
||
³ º º º º KERNAL º º º º ³
|
||
ÆÍÇÄÄÄÄÄ×ÄÄÄÄÄ×ÄÄÄÄÄ×ÄÄÄÄÄÂÄÄÄÄÄ×ÄÄÄÄÄ×ÄÄÄÄÄ×ÄÄÄÄĶ͵
|
||
³ º º º º ³LEVELºLEVELºLEVELºLEVELº ³
|
||
³ º º º º ³ 0 º 1 º 2 º 3 º ³
|
||
³ º º º ÈÍÍÍÍÍØÍÍÍÍͼ º º º ³
|
||
³ º º º ³ º º º ³
|
||
³ º º ÈÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍͼ º º ³
|
||
³ º º ³ º º ³
|
||
³ º ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ º ³
|
||
³ º ³ º ³
|
||
TASK B´ ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ ÃTASK A
|
||
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
||
|
||
|
||
6.3.2 Restricting Access to Data
|
||
|
||
To address operands in memory, an 80386 program must load the selector of a
|
||
data segment into a data-segment register (DS, ES, FS, GS, SS). The
|
||
processor automatically evaluates access to a data segment by comparing
|
||
privilege levels. The evaluation is performed at the time a selector for the
|
||
descriptor of the target segment is loaded into the data-segment register.
|
||
As Figure 6-3 shows, three different privilege levels enter into this type
|
||
of privilege check:
|
||
|
||
1. The CPL (current privilege level).
|
||
|
||
2. The RPL (requestor's privilege level) of the selector used to specify
|
||
the target segment.
|
||
|
||
3. The DPL of the descriptor of the target segment.
|
||
|
||
Instructions may load a data-segment register (and subsequently use the
|
||
target segment) only if the DPL of the target segment is numerically greater
|
||
than or equal to the maximum of the CPL and the selector's RPL. In other
|
||
words, a procedure can only access data that is at the same or less
|
||
privileged level.
|
||
|
||
The addressable domain of a task varies as CPL changes. When CPL is zero,
|
||
data segments at all privilege levels are accessible; when CPL is one, only
|
||
data segments at privilege levels one through three are accessible; when CPL
|
||
is three, only data segments at privilege level three are accessible. This
|
||
property of the 80386 can be used, for example, to prevent applications
|
||
procedures from reading or changing tables of the operating system.
|
||
|
||
|
||
Figure 6-3. Privilege Check for Data Access
|
||
|
||
16-BIT VISIBLE
|
||
SELECTOR INVISIBLE DESCRIPTOR
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍËÍÍÍÍÍÍÍÍÍÍÍ»
|
||
CS º º ºCPLº º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÑÍÊÍÍÍÍÍÍÍÍÍÍͼ
|
||
³
|
||
TARGET SEGMENT SELECTOR ³ ÉÍÍÍÍÍÍÍÍÍÍÍ»
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍËÍÍÍ» ÀÄÄÄÄÄÄĺ PRIVILEGE º
|
||
º INDEX º ºRPLÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĺ CHECK º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÊÍÍͼ ÚÄÄÄÄÄÄĺ BY CPU º
|
||
³ ÈÍÍÍÍÍÍÍÍÍÍͼ
|
||
DATA SEGMENT DESCRIPTOR ÚÄÄÄÙ
|
||
³
|
||
31 23 15 ³ 7 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÑÍÑÍÑÍÑÍÍÍÍÍÍÍÍÍØÍÑÍÍÏÍÍÑÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º ³ ³ ³ ³A³ LIMIT ³ ³ ³ TYPE ³ º
|
||
º BASE 31..24 ³G³B³0³V³ ³P³ DPL ³ ³ BASE 23..16 º 4
|
||
º ³ ³ ³ ³L³ 19..16 ³ ³ ³1³0³E³W³A³ º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÁÄÁÄÁÄÁÄÄÄÄÄÄÄÄÄÅÄÁÄÄÄÄÄÁÄÁÄÁÄÁÄÁÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º ³ º
|
||
º SEGMENT BASE 15..0 ³ SEGMENT LIMIT 15..0 º 0
|
||
º ³ º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
|
||
CPL - CURRENT PRIVILEGE LEVEL
|
||
RPL - REQUESTOR'S PRIVILEGE LEVEL
|
||
DPL - DESCRIPTOR PRIVILEGE LEVEL
|
||
|
||
|
||
6.3.2.1 Accessing Data in Code Segments
|
||
|
||
Less common than the use of data segments is the use of code segments to
|
||
store data. Code segments may legitimately hold constants; it is not
|
||
possible to write to a segment described as a code segment. The following
|
||
methods of accessing data in code segments are possible:
|
||
|
||
1. Load a data-segment register with a selector of a nonconforming,
|
||
readable, executable segment.
|
||
|
||
2. Load a data-segment register with a selector of a conforming,
|
||
readable, executable segment.
|
||
|
||
3. Use a CS override prefix to read a readable, executable segment whose
|
||
selector is already loaded in the CS register.
|
||
|
||
The same rules as for access to data segments apply to case 1. Case 2 is
|
||
always valid because the privilege level of a segment whose conforming bit
|
||
is set is effectively the same as CPL regardless of its DPL. Case 3 always
|
||
valid because the DPL of the code segment in CS is, by definition, equal to
|
||
CPL.
|
||
|
||
|
||
6.3.3 Restricting Control Transfers
|
||
|
||
With the 80386, control transfers are accomplished by the instructions JMP,
|
||
CALL, RET, INT, and IRET, as well as by the exception and interrupt
|
||
mechanisms. Exceptions and interrupts are special cases that Chapter 9
|
||
covers. This chapter discusses only JMP, CALL, and RET instructions.
|
||
|
||
The "near" forms of JMP, CALL, and RET transfer within the current code
|
||
segment, and therefore are subject only to limit checking. The processor
|
||
ensures that the destination of the JMP, CALL, or RET instruction does not
|
||
exceed the limit of the current executable segment. This limit is cached in
|
||
the CS register; therefore, protection checks for near transfers require no
|
||
extra clock cycles.
|
||
|
||
The operands of the "far" forms of JMP and CALL refer to other segments;
|
||
therefore, the processor performs privilege checking. There are two ways a
|
||
JMP or CALL can refer to another segment:
|
||
|
||
1. The operand selects the descriptor of another executable segment.
|
||
|
||
2. The operand selects a call gate descriptor. This gated form of
|
||
transfer is discussed in a later section on call gates.
|
||
|
||
As Figure 6-4 shows, two different privilege levels enter into a privilege
|
||
check for a control transfer that does not use a call gate:
|
||
|
||
1. The CPL (current privilege level).
|
||
2. The DPL of the descriptor of the target segment.
|
||
|
||
Normally the CPL is equal to the DPL of the segment that the processor is
|
||
currently executing. CPL may, however, be greater than DPL if the conforming
|
||
bit is set in the descriptor of the current executable segment. The
|
||
processor keeps a record of the CPL cached in the CS register; this value
|
||
can be different from the DPL in the descriptor of the code segment.
|
||
|
||
The processor permits a JMP or CALL directly to another segment only if one
|
||
of the following privilege rules is satisfied:
|
||
|
||
þ DPL of the target is equal to CPL.
|
||
|
||
þ The conforming bit of the target code-segment descriptor is set, and
|
||
the DPL of the target is less than or equal to CPL.
|
||
|
||
An executable segment whose descriptor has the conforming bit set is called
|
||
a conforming segment. The conforming-segment mechanism permits sharing of
|
||
procedures that may be called from various privilege levels but should
|
||
execute at the privilege level of the calling procedure. Examples of such
|
||
procedures include math libraries and some exception handlers. When control
|
||
is transferred to a conforming segment, the CPL does not change. This is
|
||
the only case when CPL may be unequal to the DPL of the current executable
|
||
segment.
|
||
|
||
Most code segments are not conforming. The basic rules of privilege above
|
||
mean that, for nonconforming segments, control can be transferred without a
|
||
gate only to executable segments at the same level of privilege. There is a
|
||
need, however, to transfer control to (numerically) smaller privilege
|
||
levels; this need is met by the CALL instruction when used with call-gate
|
||
descriptors, which are explained in the next section. The JMP instruction
|
||
may never transfer control to a nonconforming segment whose DPL does not
|
||
equal CPL.
|
||
|
||
|
||
Figure 6-4. Privilege Check for Control Transfer without Gate
|
||
|
||
16-BIT VISIBLE
|
||
SELECTOR INVISIBLE PART
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍËÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º º ºCPLº º CS
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÑÍÊÍÍÍÍÍÍÍÍÍÍͼ
|
||
³
|
||
³ ÉÍÍÍÍÍÍÍÍÍÍÍ»
|
||
ÀÄÄÄÄÄÄĺ PRIVILEGE º
|
||
ÚÄÄÄÄÄÄÄÄÄÄĺ CHECK º
|
||
³ ÚÄÄĺ BY CPU º
|
||
CODE-SEGMENT DESCRIPTOR ³ ³ ÈÍÍÍÍÍÍÍÍÍÍͼ
|
||
³ ³
|
||
31 23 15 ³ ³ 7 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÑÍÑÍÑÍÑÍÍÍÍÍÍÍÍÍØÍÑÍÍÏÍÍÑÍÍÍÍØÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º ³ ³ ³ ³A³ LIMIT ³ ³ ³ ³ ³ º
|
||
º BASE 31..24 ³G³D³0³V³ ³P³ DPL ³ ³ ³ BASE 23..16 º 4
|
||
º ³ ³ ³ ³L³ 19..16 ³ ³ ³1³1³C³R³A³ º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÁÄÁÄÁÄÁÄÄÄÄÄÄÄÄÄÅÄÁÄÄÄÄÄÁÄÁÄÁÄÁÄÁÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º ³ º
|
||
º SEGMENT BASE 15..0 ³ SEGMENT LIMIT 15..0 º 0
|
||
º ³ º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
CPL - CURRENT PRIVILEGE LEVEL
|
||
DPL - DESCRIPTOR PRIVILEGE LEVEL
|
||
C - CONFORMING BIT
|
||
|
||
|
||
6.3.4 Gate Descriptors Guard Procedure Entry Points
|
||
|
||
To provide protection for control transfers among executable segments
|
||
at different privilege levels, the 80386 uses gate descriptors. There are
|
||
four kinds of gate descriptors:
|
||
|
||
þ Call gates
|
||
þ Trap gates
|
||
þ Interrupt gates
|
||
þ Task gates
|
||
|
||
This chapter is concerned only with call gates. Task gates are used for
|
||
task switching, and therefore are discussed in Chapter 7. Chapter 9
|
||
explains how trap gates and interrupt gates are used by exceptions and
|
||
interrupts. Figure 6-5 illustrates the format of a call gate. A call gate
|
||
descriptor may reside in the GDT or in an LDT, but not in the IDT.
|
||
|
||
A call gate has two primary functions:
|
||
|
||
1. To define an entry point of a procedure.
|
||
2. To specify the privilege level of the entry point.
|
||
|
||
Call gate descriptors are used by call and jump instructions in the same
|
||
manner as code segment descriptors. When the hardware recognizes that the
|
||
destination selector refers to a gate descriptor, the operation of the
|
||
instruction is expanded as determined by the contents of the call gate.
|
||
|
||
The selector and offset fields of a gate form a pointer to the entry point
|
||
of a procedure. A call gate guarantees that all transitions to another
|
||
segment go to a valid entry point, rather than possibly into the middle of a
|
||
procedure (or worse, into the middle of an instruction). The far pointer
|
||
operand of the control transfer instruction does not point to the segment
|
||
and offset of the target instruction; rather, the selector part of the
|
||
pointer selects a gate, and the offset is not used. Figure 6-6 illustrates
|
||
this style of addressing.
|
||
|
||
As Figure 6-7 shows, four different privilege levels are used to check the
|
||
validity of a control transfer via a call gate:
|
||
|
||
1. The CPL (current privilege level).
|
||
|
||
2. The RPL (requestor's privilege level) of the selector used to specify
|
||
the call gate.
|
||
|
||
3. The DPL of the gate descriptor.
|
||
|
||
4. The DPL of the descriptor of the target executable segment.
|
||
|
||
The DPL field of the gate descriptor determines what privilege levels can
|
||
use the gate. One code segment can have several procedures that are intended
|
||
for use by different privilege levels. For example, an operating system may
|
||
have some services that are intended to be used by applications, whereas
|
||
others may be intended only for use by other systems software.
|
||
|
||
Gates can be used for control transfers to numerically smaller privilege
|
||
levels or to the same privilege level (though they are not necessary for
|
||
transfers to the same level). Only CALL instructions can use gates to
|
||
transfer to smaller privilege levels. A gate may be used by a JMP
|
||
instruction only to transfer to an executable segment with the same
|
||
privilege level or to a conforming segment.
|
||
|
||
For a JMP instruction to a nonconforming segment, both of the following
|
||
privilege rules must be satisfied; otherwise, a general protection exception
|
||
results.
|
||
|
||
MAX (CPL,RPL) ó gate DPL
|
||
target segment DPL = CPL
|
||
|
||
For a CALL instruction (or for a JMP instruction to a conforming segment),
|
||
both of the following privilege rules must be satisfied; otherwise, a
|
||
general protection exception results.
|
||
|
||
MAX (CPL,RPL) ó gate DPL
|
||
target segment DPL ó CPL
|
||
|
||
|
||
Figure 6-5. Format of 80386 Call Gate
|
||
|
||
31 23 15 7 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÑÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍ»
|
||
º ³ ³ ³ TYPE ³ ³ DWORD º
|
||
º OFFSET 31..16 ³P³ DPL ³ ³0 0 0³ º 4
|
||
º ³ ³ ³0 1 1 0 0³ ³ COUNT º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÁÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÄÄÄĶ
|
||
º ³ º
|
||
º SELECTOR ³ OFFSET 15..0 º 0
|
||
º ³ º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
|
||
Figure 6-6. Indirect Transfer via Call Gate
|
||
|
||
OPCODE OFFSET SELECTOR
|
||
ÉÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍËÍËÍÍÍ»
|
||
º CALL º (NOT USED) º INDEX º ºRPLº
|
||
ÈÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÑÍÍÍÊÍÊÍÍͼ
|
||
³
|
||
DESCRIPTOR TABLE ³
|
||
ÉÍÍÍÍÍÍÑÍÍÍÍÍÑÍÍÍÍÍÑÍÍÍÍÍÍ» ³
|
||
º ³ ³ ³ º ³
|
||
ÇÄÄÄÄÄÄÁÄÄÄÄÄÅÄÄÄÄÄÁÄÄÄÄÄĶ ³
|
||
º ³ º ³
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍͼ ³
|
||
³
|
||
³
|
||
³
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÑÍÍÍÍÍÍ» ³
|
||
GATE º OFFSET ³ DPL ³COUNT ºÄÄÄÄÄÄÄÄÄÄÄÄÄÙ EXECUTABLE
|
||
DESCRIPTOR ÇÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÁÄÄÄÄÄĶ SEGMENT
|
||
ÚÄÄÄÄÄĶ SELECTOR ³ OFFSET ÇÄÄÄÄÄ¿ ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
³ ÌÍÍÍÍÍÍÑÍÍÍÍÍØÍÍÍÍÍÑÍÍÍÍÍ͹ ³ º º
|
||
³ º ³ ³ ³ º ³ º º
|
||
³ ÇÄÄÄÄÄÄÁÄÄÄÄÄÅÄÄÄÄÄÁÄÄÄÄÄĶ ³ º º
|
||
³ º ³ º ³ º º
|
||
³ ÌÍÍÍÍÍÍÑÍÍÍÍÍØÍÍÍÍÍÑÍÍÍÍÍ͹ ³ º º
|
||
³ º ³ ³ ³ º ÀÄÄÄÄÄÄÄÄĺ PROCEDURE º
|
||
³ ÇÄÄÄÄÄÄÁÄÄÄÄÄÅÄÄÄÄÄÁÄÄÄÄÄĶ º º
|
||
³ º ³ º º º
|
||
ÌÍÍÍÍÍÍÑÍÍÍÍÍØÍÍÍÍÍÑÍÍÍÍÍ͹ º º
|
||
EXECUTABLE º BASE ³ ³ DPL ³ BASE º º º
|
||
SEGMENT ÇÄÄÄÄÄÄÁÄÄÄÄÄÅÄÄÄÄÄÁÄÄÄÄÄĶ ÚÄÄÄÄÄÄÄÄÄÈÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
DESCRIPTOR º BASE ³ ÇÄÄÄÄÄÙ
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
|
||
|
||
ÉÍÍÍÍÍÍÑÍÍÍÍÍÑÍÍÍÍÍÑÍÍÍÍÍÍ»
|
||
º ³ ³ ³ º
|
||
ÇÄÄÄÄÄÄÁÄÄÄÄÄÅÄÄÄÄÄÁÄÄÄÄÄĶ
|
||
º ³ º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
|
||
Figure 6-7. Privilege Check via Call Gate
|
||
|
||
16-BIT VISIBLE
|
||
SELECTOR INVISIBLE DESCRIPTOR
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍËÍÍÍÍÍÍÍÍÍÍÍ»
|
||
CS º º ºCPLº º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÑÍÊÍÍÍÍÍÍÍÍÍÍͼ
|
||
³
|
||
TARGET SELECTOR ³ ÉÍÍÍÍÍÍÍÍÍÍÍ»
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍËÍÍÍ» ÀÄÄÄÄÄÄĺ PRIVILEGE º
|
||
º INDEX º ºRPLÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĺ CHECK º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÊÍÍͼ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĺ BY º
|
||
³ ÚÄĺ CPU º
|
||
ÚÄÄÄÄÄÄÙ ³ ÈÍÍÍÍÍÍÍÍÍÍͼ
|
||
³ ³
|
||
GATE DESCRIPTOR ³
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍ» ³
|
||
º OFFSET º DPL º COUNT º ³
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍ͹ ³
|
||
º SELECTOR º OFFSET º ³
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ ³
|
||
³
|
||
³
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÏÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍ»
|
||
EXECUTABLE º BASE º LIMIT º DPL º BASE º
|
||
SEGMENT ÌÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍ͹
|
||
DESCRIPTOR º BASE º LIMIT º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
CPL - CURRENT PRIVILEGE LEVEL
|
||
RPL - REQUESTOR'S PRIVILEGE LEVEL
|
||
DPL - DESCRIPTOR PRIVILEGE LEVEL
|
||
|
||
|
||
6.3.4.1 Stack Switching
|
||
|
||
If the destination code segment of the call gate is at a different
|
||
privilege level than the CPL, an interlevel transfer is being requested.
|
||
|
||
To maintain system integrity, each privilege level has a separate stack.
|
||
These stacks assure sufficient stack space to process calls from less
|
||
privileged levels. Without them, a trusted procedure would not work
|
||
correctly if the calling procedure did not provide sufficient space on the
|
||
caller's stack.
|
||
|
||
The processor locates these stacks via the task state segment (see Figure
|
||
6-8). Each task has a separate TSS, thereby permitting tasks to have
|
||
separate stacks. Systems software is responsible for creating TSSs and
|
||
placing correct stack pointers in them. The initial stack pointers in the
|
||
TSS are strictly read-only values. The processor never changes them during
|
||
the course of execution.
|
||
|
||
When a call gate is used to change privilege levels, a new stack is
|
||
selected by loading a pointer value from the Task State Segment (TSS). The
|
||
processor uses the DPL of the target code segment (the new CPL) to index the
|
||
initial stack pointer for PL 0, PL 1, or PL 2.
|
||
|
||
The DPL of the new stack data segment must equal the new CPL; if it does
|
||
not, a stack exception occurs. It is the responsibility of systems software
|
||
to create stacks and stack-segment descriptors for all privilege levels that
|
||
are used. Each stack must contain enough space to hold the old SS:ESP, the
|
||
return address, and all parameters and local variables that may be required
|
||
to process a call.
|
||
|
||
As with intralevel calls, parameters for the subroutine are placed on the
|
||
stack. To make privilege transitions transparent to the called procedure,
|
||
the processor copies the parameters to the new stack. The count field of a
|
||
call gate tells the processor how many doublewords (up to 31) to copy from
|
||
the caller's stack to the new stack. If the count is zero, no parameters are
|
||
copied.
|
||
|
||
The processor performs the following stack-related steps in executing an
|
||
interlevel CALL.
|
||
|
||
1. The new stack is checked to assure that it is large enough to hold
|
||
the parameters and linkages; if it is not, a stack fault occurs with
|
||
an error code of 0.
|
||
|
||
2. The old value of the stack registers SS:ESP is pushed onto the new
|
||
stack as two doublewords.
|
||
|
||
3. The parameters are copied.
|
||
|
||
4. A pointer to the instruction after the CALL instruction (the former
|
||
value of CS:EIP) is pushed onto the new stack. The final value of
|
||
SS:ESP points to this return pointer on the new stack.
|
||
|
||
Figure 6-9 illustrates the stack contents after a successful interlevel
|
||
call.
|
||
|
||
The TSS does not have a stack pointer for a privilege level 3 stack,
|
||
because privilege level 3 cannot be called by any procedure at any other
|
||
privilege level.
|
||
|
||
Procedures that may be called from another privilege level and that require
|
||
more than the 31 doublewords for parameters must use the saved SS:ESP link
|
||
to access all parameters beyond the last doubleword copied.
|
||
|
||
A call via a call gate does not check the values of the words copied onto
|
||
the new stack. The called procedure should check each parameter for
|
||
validity. A later section discusses how the ARPL, VERR, VERW, LSL, and LAR
|
||
instructions can be used to check pointer values.
|
||
|
||
|
||
Figure 6-8. Initial Stack Pointers of TSS
|
||
|
||
31 23 15 7 0
|
||
ÉÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍ»64
|
||
|
||
|
||
|
||
º º
|
||
ÌÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍ͹
|
||
º EFLAGS º24
|
||
ÌÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍ͹
|
||
º INSTRUCTION POINTER (EIP) º20
|
||
ÌÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍ͹
|
||
º CR3 (PDBR) º1C
|
||
ÌÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍØÍÍÍÍÍËÍ͹ Ä¿
|
||
º00000000 00000000º SS2 º10º18 ³
|
||
ÌÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍØÍÍÍÍÍÊÍ͹ ³
|
||
º ESP2 º14 ³
|
||
ÌÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍØÍÍÍÍÍËÍ͹ ³
|
||
º00000000 00000000º SS1 º01º10 ³ INITIAL
|
||
ÌÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍØÍÍÍÍÍÊÍ͹ ÃÄ STACK
|
||
º ESP1 º0C ³ POINTERS
|
||
ÌÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍØÍÍÍÍÍËÍ͹ ³
|
||
º00000000 00000000º SS0 º00º8 ³
|
||
ÌÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍØÍÍÍÍÍÊÍ͹ ³
|
||
º ESP0 º4 ³
|
||
ÌÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍ͹ ÄÙ
|
||
º00000000 00000000º TSS BACK LINK º0
|
||
ÈÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍͼ
|
||
|
||
|
||
Figure 6-9. Stack Contents after an Interlevel Call
|
||
|
||
31 0 SS:ESP
|
||
ÉÍÍÍÍÍÍÍØÍÍÍÍÍÍÍ»ÄÄFROM TSS
|
||
31 0 º±±±±±±±³OLD SS º
|
||
ÉÍÍÍÍÍÍÍØÍÍÍÍÍÍÍ» ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
D O º º º OLD ESP º
|
||
I F º º ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
R º º º PARM 3 º
|
||
E E º º ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
C X º º º PARM 2 º
|
||
T P ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
I A º PARM 3 º º PARM 1 º
|
||
O N ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
||
N S º PARM 2 º º±±±±±±±³OLD CS º NEW
|
||
I ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ OLD ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ SS:ESP
|
||
³ O º PARM 1 º SS:ESP º OLD EIP º ³
|
||
³ N ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ÄÄÄÙ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ÄÄÄÄÄÙ
|
||
³ º º º º
|
||
º º º º
|
||
ÈÍÍÍÍÍÍÍØÍÍÍÍÍÍͼ ÈÍÍÍÍÍÍÍØÍÍÍÍÍÍͼ
|
||
OLD STACK NEW STACK
|
||
|
||
|
||
6.3.4.2 Returning from a Procedure
|
||
|
||
The "near" forms of the RET instruction transfer control within the current
|
||
code segment and therefore are subject only to limit checking. The offset of
|
||
the instruction following the corresponding CALL, is popped from the stack.
|
||
The processor ensures that this offset does not exceed the limit of the
|
||
current executable segment.
|
||
|
||
The "far" form of the RET instruction pops the return pointer that was
|
||
pushed onto the stack by a prior far CALL instruction. Under normal
|
||
conditions, the return pointer is valid, because of its relation to the
|
||
prior CALL or INT. Nevertheless, the processor performs privilege checking
|
||
because of the possibility that the current procedure altered the pointer or
|
||
failed to properly maintain the stack. The RPL of the CS selector popped
|
||
off the stack by the return instruction identifies the privilege level of
|
||
the calling procedure.
|
||
|
||
An intersegment return instruction can change privilege levels, but only
|
||
toward procedures of lesser privilege. When the RET instruction encounters a
|
||
saved CS value whose RPL is numerically greater than the CPL, an interlevel
|
||
return occurs. Such a return follows these steps:
|
||
|
||
1. The checks shown in Table 6-3 are made, and CS:EIP and SS:ESP are
|
||
loaded with their former values that were saved on the stack.
|
||
|
||
2. The old SS:ESP (from the top of the current stack) value is adjusted
|
||
by the number of bytes indicated in the RET instruction. The resulting
|
||
ESP value is not compared to the limit of the stack segment. If ESP is
|
||
beyond the limit, that fact is not recognized until the next stack
|
||
operation. (The SS:ESP value of the returning procedure is not
|
||
preserved; normally, this value is the same as that contained in the
|
||
TSS.)
|
||
|
||
3. The contents of the DS, ES, FS, and GS segment registers are checked.
|
||
If any of these registers refer to segments whose DPL is greater than
|
||
the new CPL (excluding conforming code segments), the segment register
|
||
is loaded with the null selector (INDEX = 0, TI = 0). The RET
|
||
instruction itself does not signal exceptions in these cases;
|
||
however, any subsequent memory reference that attempts to use a
|
||
segment register that contains the null selector will cause a general
|
||
protection exception. This prevents less privileged code from
|
||
accessing more privileged segments using selectors left in the
|
||
segment registers by the more privileged procedure.
|
||
|
||
|
||
6.3.5 Some Instructions are Reserved for Operating System
|
||
|
||
Instructions that have the power to affect the protection mechanism or to
|
||
influence general system performance can only be executed by trusted
|
||
procedures. The 80386 has two classes of such instructions:
|
||
|
||
1. Privileged instructions ÄÄ those used for system control.
|
||
|
||
2. Sensitive instructions ÄÄ those used for I/O and I/O related
|
||
activities.
|
||
|
||
|
||
Table 6-3. Interlevel Return Checks
|
||
|
||
|
||
Type of Check Exception
|
||
SF Stack Fault
|
||
GP General Protection Exception
|
||
NP Segment-Not-Present Exception Error Code
|
||
|
||
ESP is within current SS segment SF 0
|
||
ESP + 7 is within current SS segment SF 0
|
||
RPL of return CS is greater than CPL GP Return CS
|
||
Return CS selector is not null GP Return CS
|
||
Return CS segment is within descriptor
|
||
table limit GP Return CS
|
||
Return CS descriptor is a code segment GP Return CS
|
||
Return CS segment is present NP Return CS
|
||
DPL of return nonconforming code
|
||
segment = RPL of return CS, or DPL of
|
||
return conforming code segment ó RPL
|
||
of return CS GP Return CS
|
||
ESP + N + 15 is within SS segment
|
||
N Immediate Operand of RET N Instruction SF Return SS
|
||
SS selector at ESP + N + 12 is not null GP Return SS
|
||
SS selector at ESP + N + 12 is within
|
||
descriptor table limit GP Return SS
|
||
SS descriptor is writable data segment GP Return SS
|
||
SS segment is present SF Return SS
|
||
Saved SS segment DPL = RPL of saved
|
||
CS GP Return SS
|
||
Saved SS selector RPL = Saved SS
|
||
segment DPL GP Return SS
|
||
|
||
|
||
6.3.5.1 Privileged Instructions
|
||
|
||
The instructions that affect system data structures can only be executed
|
||
when CPL is zero. If the CPU encounters one of these instructions when CPL
|
||
is greater than zero, it signals a general protection exception. These
|
||
instructions include:
|
||
|
||
CLTS ÄÄ Clear TaskÄSwitched Flag
|
||
HLT ÄÄ Halt Processor
|
||
LGDT ÄÄ Load GDL Register
|
||
LIDT ÄÄ Load IDT Register
|
||
LLDT ÄÄ Load LDT Register
|
||
LMSW ÄÄ Load Machine Status Word
|
||
LTR ÄÄ Load Task Register
|
||
MOV to/from CRn ÄÄ Move to Control Register n
|
||
MOV to /from DRn ÄÄ Move to Debug Register n
|
||
MOV to/from TRn ÄÄ Move to Test Register n
|
||
|
||
|
||
6.3.5.2 Sensitive Instructions
|
||
|
||
Instructions that deal with I/O need to be restricted but also need to be
|
||
executed by procedures executing at privilege levels other than zero. The
|
||
mechanisms for restriction of I/O operations are covered in detail in
|
||
Chapter 8, "Input/Output".
|
||
|
||
|
||
6.3.6 Instructions for 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.
|
||
|
||
Although the 80386 processor automatically performs checks 2 and 3 during
|
||
instruction execution, software must assist in performing the first check.
|
||
The unprivileged instruction ARPL is provided for this purpose. Software can
|
||
also explicitly perform steps 2 and 3 to check for potential violations
|
||
(rather than waiting for an exception). The unprivileged instructions LAR,
|
||
LSL, VERR, and VERW are provided for this purpose.
|
||
|
||
LAR (Load Access Rights) is used to verify that a pointer refers to a
|
||
segment of the proper privilege level and type. LAR has one operandÄÄa
|
||
selector for a descriptor whose access rights are to be examined. The
|
||
descriptor must be visible at the privilege level which is the maximum of
|
||
the CPL and the selector's RPL. If the descriptor is visible, LAR obtains a
|
||
masked form of the second doubleword of the descriptor, masks this value
|
||
with 00FxFF00H, stores the result into the specified 32-bit destination
|
||
register, and sets the zero flag. (The x indicates that the corresponding
|
||
four bits of the stored value are undefined.) Once loaded, the access-rights
|
||
bits can be tested. All valid descriptor types can be tested by the LAR
|
||
instruction. If the RPL or CPL is greater than DPL, or if the selector is
|
||
outside the table limit, no access-rights value is returned, and the zero
|
||
flag is cleared. Conforming code segments may be accessed from any privilege
|
||
level.
|
||
|
||
LSL (Load Segment Limit) allows software to test the limit of a descriptor.
|
||
If the descriptor denoted by the given selector (in memory or a register) is
|
||
visible at the CPL, LSL loads the specified 32-bit register with a 32-bit,
|
||
byte granular, unscrambled limit that is calculated from fragmented limit
|
||
fields and the G-bit of that descriptor. This can only be done for segments
|
||
(data, code, task state, and local descriptor tables); gate descriptors are
|
||
inaccessible. (Table 6-4 lists in detail which types are valid and which
|
||
are not.) 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 ZF is cleared.
|
||
|
||
|
||
Table 6-4. Valid Descriptor Types for LSL
|
||
|
||
Type Descriptor Type Valid?
|
||
Code
|
||
|
||
0 (invalid) NO
|
||
1 Available 286 TSS YES
|
||
2 LDT YES
|
||
3 Busy 286 TSS YES
|
||
4 286 Call Gate NO
|
||
5 Task Gate NO
|
||
6 286 Trap Gate NO
|
||
7 286 Interrupt Gate NO
|
||
8 (invalid) NO
|
||
9 Available 386 TSS YES
|
||
A (invalid) NO
|
||
B Busy 386 TSS YES
|
||
C 386 Call Gate NO
|
||
D (invalid) NO
|
||
E 386 Trap Gate NO
|
||
F 386 Interrupt Gate NO
|
||
|
||
|
||
6.3.6.1 Descriptor Validation
|
||
|
||
The 80386 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 (Verify for Reading) verifies a segment for reading and loads ZF with
|
||
1 if that segment is readable from the current privilege level. VERR checks
|
||
that:
|
||
|
||
þ The selector points to a descriptor within the bounds of the GDT or
|
||
LDT.
|
||
|
||
þ It denotes a code or data segment descriptor.
|
||
|
||
þ The segment is readable and of appropriate privilege level.
|
||
|
||
The privilege check for data segments and nonconforming 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 (Verify for Writing) 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 or equal to both the CPL and the selector's
|
||
RPL. Code segments are never writable, conforming or not.
|
||
|
||
|
||
6.3.6.2 Pointer Integrity and RPL
|
||
|
||
The Requestor's 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, n_bytes,
|
||
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.
|
||
|
||
Use of RPL 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 80386 processor automatically checks the RPL of any selector
|
||
loaded into a segment register to determine whether the RPL allows access.
|
||
|
||
To take advantage of the processor's checking of RPL, 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 action guarantees that
|
||
selectors are 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 that selector is loaded into a segment
|
||
register.
|
||
|
||
ARPL (Adjust Requestor's Privilege Level) 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 image
|
||
of the caller's CS register which is on the stack. If the adjustment changes
|
||
the selector's RPL, ZF (the zero flag) is set; otherwise, ZF is cleared.
|
||
|
||
|
||
6.4 Page-Level Protection
|
||
|
||
Two kinds of protection are related to pages:
|
||
|
||
1. Restriction of addressable domain.
|
||
2. Type checking.
|
||
|
||
|
||
6.4.1 Page-Table Entries Hold Protection Parameters
|
||
|
||
Figure 6-10 highlights the fields of PDEs and PTEs that control access to
|
||
pages.
|
||
|
||
|
||
Figure 6-10. Protection Fields of Page Table Entries
|
||
|
||
31 12 11 7 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÑÍÍÍÑÍÑÍÑÍÍÍÑÍÑÍÑÍ»
|
||
º±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±³±±±±±±±³±±±³±³±³±±±³U³R³±º
|
||
º±±±±±±PAGE FRAME ADDRESS 31..12±±±±±±±³±AVAIL±³0±0³D³A³0±0³/³/³Pº
|
||
º±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±³±±±±±±±³±±±³±³±³±±±³S³W³±º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÏÍÍÍÏÍÏÍÏÍÍÍÏÍÏÍÏͼ
|
||
R/W - READ/WRITE
|
||
U/S - USER/SUPERVISOR
|
||
|
||
|
||
6.4.1.1 Restricting Addressable Domain
|
||
|
||
The concept of privilege for pages is implemented by assigning each page to
|
||
one of two levels:
|
||
|
||
1. Supervisor level (U/S=0) ÄÄ for the operating system and other systems
|
||
software and related data.
|
||
|
||
2. User level (U/S=1) ÄÄ for applications procedures and data.
|
||
|
||
The current level (U or S) is related to CPL. If CPL is 0, 1, or 2, the
|
||
processor is executing at supervisor level. If CPL is 3, the processor is
|
||
executing at user level.
|
||
|
||
When the processor is executing at supervisor level, all pages are
|
||
addressable, but, when the processor is executing at user level, only pages
|
||
that belong to the user level are addressable.
|
||
|
||
|
||
6.4.1.2 Type Checking
|
||
|
||
At the level of page addressing, two types are defined:
|
||
|
||
1. Read-only access (R/W=0)
|
||
2. Read/write access (R/W=1)
|
||
|
||
When the processor is executing at supervisor level, all pages are both
|
||
readable and writable. When the processor is executing at user level, only
|
||
pages that belong to user level and are marked for read/write access are
|
||
writable; pages that belong to supervisor level are neither readable nor
|
||
writable from user level.
|
||
|
||
|
||
6.4.2 Combining Protection of Both Levels of Page Tables
|
||
|
||
For any one page, the protection attributes of its page directory entry may
|
||
differ from those of its page table entry. The 80386 computes the effective
|
||
protection attributes for a page by examining the protection attributes in
|
||
both the directory and the page table. Table 6-5 shows the effective
|
||
protection provided by the possible combinations of protection attributes.
|
||
|
||
|
||
6.4.3 Overrides to Page Protection
|
||
|
||
Certain accesses are checked as if they are privilege-level 0 references,
|
||
even if CPL = 3:
|
||
|
||
þ LDT, GDT, TSS, IDT references.
|
||
þ Access to inner stack during ring-crossing CALL/INT.
|
||
|
||
|
||
6.5 Combining Page and Segment Protection
|
||
|
||
When paging is enabled, the 80386 first evaluates segment protection, then
|
||
evaluates page protection. If the processor detects a protection violation
|
||
at either the segment or the page level, the requested operation cannot
|
||
proceed; a protection exception occurs instead.
|
||
|
||
For example, it is possible to define a large data segment which has some
|
||
subunits that are read-only and other subunits that are read-write. In this
|
||
case, the page directory (or page table) entries for the read-only subunits
|
||
would have the U/S and R/W bits set to x0, indicating no write rights for
|
||
all the pages described by that directory entry (or for individual pages).
|
||
This technique might be used, for example, in a UNIX-like system to define
|
||
a large data segment, part of which is read only (for shared data or ROMmed
|
||
constants). This enables UNIX-like systems to define a "flat" data space as
|
||
one large segment, use "flat" pointers to address within this "flat" space,
|
||
yet be able to protect shared data, shared files mapped into the virtual
|
||
space, and supervisor areas.
|
||
|
||
|
||
Table 6-5. Combining Directory and Page Protection
|
||
|
||
Page Directory Entry Page Table Entry Combined Protection
|
||
U/S R/W U/S R/W U/S R/W
|
||
|
||
S-0 R-0 S-0 R-0 S x
|
||
S-0 R-0 S-0 W-1 S x
|
||
S-0 R-0 U-1 R-0 S x
|
||
S-0 R-0 U-1 W-1 S x
|
||
S-0 W-1 S-0 R-0 S x
|
||
S-0 W-1 S-0 W-1 S x
|
||
S-0 W-1 U-1 R-0 S x
|
||
S-0 W-1 U-1 W-1 S x
|
||
U-1 R-0 S-0 R-0 S x
|
||
U-1 R-0 S-0 W-1 S x
|
||
U-1 R-0 U-1 R-0 U R
|
||
U-1 R-0 U-1 W-1 U R
|
||
U-1 W-1 S-0 R-0 S x
|
||
U-1 W-1 S-0 W-1 S x
|
||
U-1 W-1 U-1 R-0 U R
|
||
U-1 W-1 U-1 W-1 U W
|
||
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
NOTE
|
||
S ÄÄ Supervisor
|
||
R ÄÄ Read only
|
||
U ÄÄ User
|
||
W ÄÄ Read and Write
|
||
x indicates that when the combined U/S attribute is S, the R/W attribute
|
||
is not checked.
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
|
||
Chapter 7 Multitasking
|
||
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
To provide efficient, protected multitasking, the 80386 employs several
|
||
special data structures. It does not, however, use special instructions to
|
||
control multitasking; instead, it interprets ordinary control-transfer
|
||
instructions differently when they refer to the special data structures. The
|
||
registers and data structures that support multitasking are:
|
||
|
||
þ Task state segment
|
||
þ Task state segment descriptor
|
||
þ Task register
|
||
þ Task gate descriptor
|
||
|
||
With these structures the 80386 can rapidly switch execution from one task
|
||
to another, saving the context of the original task so that the task can be
|
||
restarted later. In addition to the simple task switch, the 80386 offers two
|
||
other task-management features:
|
||
|
||
1. Interrupts and exceptions can cause task switches (if needed in the
|
||
system design). The processor not only switches automatically to the
|
||
task that handles the interrupt or exception, but it automatically
|
||
switches back to the interrupted task when the interrupt or exception
|
||
has been serviced. Interrupt tasks may interrupt lower-priority
|
||
interrupt tasks to any depth.
|
||
|
||
2. With each switch to another task, the 80386 can also switch to
|
||
another LDT and to another page directory. Thus each task can have a
|
||
different logical-to-linear mapping and a different linear-to-physical
|
||
mapping. This is yet another protection feature, because tasks can be
|
||
isolated and prevented from interfering with one another.
|
||
|
||
|
||
7.1 Task State Segment
|
||
|
||
All the information the processor needs in order to manage a task is stored
|
||
in a special type of segment, a task state segment (TSS). Figure 7-1 shows
|
||
the format of a TSS for executing 80386 tasks. (Another format is used for
|
||
executing 80286 tasks; refer to Chapter 13.)
|
||
|
||
The fields of a TSS belong to two classes:
|
||
|
||
1. A dynamic set that the processor updates with each switch from the
|
||
task. This set includes the fields that store:
|
||
|
||
þ The general registers (EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI).
|
||
|
||
þ The segment registers (ES, CS, SS, DS, FS, GS).
|
||
|
||
þ The flags register (EFLAGS).
|
||
|
||
þ The instruction pointer (EIP).
|
||
|
||
þ The selector of the TSS of the previously executing task (updated
|
||
only when a return is expected).
|
||
|
||
2. A static set that the processor reads but does not change. This set
|
||
includes the fields that store:
|
||
|
||
þ The selector of the task's LDT.
|
||
|
||
þ The register (PDBR) that contains the base address of the task's
|
||
page directory (read only when paging is enabled).
|
||
|
||
þ Pointers to the stacks for privilege levels 0-2.
|
||
|
||
þ The T-bit (debug trap bit) which causes the processor to raise a
|
||
debug exception when a task switch occurs. (Refer to Chapter 12
|
||
for more information on debugging.)
|
||
|
||
þ The I/O map base (refer to Chapter 8 for more information on the
|
||
use of the I/O map).
|
||
|
||
Task state segments may reside anywhere in the linear space. The only case
|
||
that requires caution is when the TSS spans a page boundary and the
|
||
higher-addressed page is not present. In this case, the processor raises an
|
||
exception if it encounters the not-present page while reading the TSS during
|
||
a task switch. Such an exception can be avoided by either of two strategies:
|
||
|
||
1. By allocating the TSS so that it does not cross a page boundary.
|
||
|
||
2. By ensuring that both pages are either both present or both
|
||
not-present at the time of a task switch. If both pages are
|
||
not-present, then the page-fault handler must make both pages present
|
||
before restarting the instruction that caused the task switch.
|
||
|
||
|
||
Figure 7-1. 80386 32-Bit Task State Segment
|
||
|
||
31 23 15 7 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ»
|
||
º I/O MAP BASE º 0 0 0 0 0 0 0 0 0 0 0 0 0 ºTº64
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÐĶ
|
||
º0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0º LDT º60
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0º GS º5C
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0º FS º58
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0º DS º54
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0º SS º50
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0º CS º4C
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0º ES º48
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º EDI º44
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º ESI º40
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º EBP º3C
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º ESP º38
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º EBX º34
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º EDX º30
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
º ECX º2C
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º EAX º28
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º EFLAGS º24
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º INSTRUCTION POINTER (EIP) º20
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º CR3 (PDPR) º1C
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0º SS2 º18
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º ESP2 º14
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0º SS1 º10
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º ESP1 º0C
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0º SS0 º8
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º ESP0 º4
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0º BACK LINK TO PREVIOUS TSS º0
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
NOTE
|
||
0 MEANS INTEL RESERVED. DO NOT DEFINE.
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
|
||
7.2 TSS Descriptor
|
||
|
||
The task state segment, like all other segments, is defined by a
|
||
descriptor. Figure 7-2 shows the format of a TSS descriptor.
|
||
|
||
The B-bit in the type field indicates whether the task is busy. A type code
|
||
of 9 indicates a non-busy task; a type code of 11 indicates a busy task.
|
||
Tasks are not reentrant. The B-bit allows the processor to detect an attempt
|
||
to switch to a task that is already busy.
|
||
|
||
The BASE, LIMIT, and DPL fields and the G-bit and P-bit have functions
|
||
similar to their counterparts in data-segment descriptors. The LIMIT field,
|
||
however, must have a value equal to or greater than 103. An attempt to
|
||
switch to a task whose TSS descriptor has a limit less that 103 causes an
|
||
exception. A larger limit is permissible, and a larger limit is required if
|
||
an I/O permission map is present. A larger limit may also be convenient for
|
||
systems software if additional data is stored in the same segment as the
|
||
TSS.
|
||
|
||
A procedure that has access to a TSS descriptor can cause a task switch. In
|
||
most systems the DPL fields of TSS descriptors should be set to zero, so
|
||
that only trusted software has the right to perform task switching.
|
||
|
||
Having access to a TSS-descriptor does not give a procedure the right to
|
||
read or modify a TSS. Reading and modification can be accomplished only with
|
||
another descriptor that redefines the TSS as a data segment. An attempt to
|
||
load a TSS descriptor into any of the segment registers (CS, SS, DS, ES, FS,
|
||
GS) causes an exception.
|
||
|
||
TSS descriptors may reside only in the GDT. An attempt to identify a TSS
|
||
with a selector that has TI=1 (indicating the current LDT) results in an
|
||
exception.
|
||
|
||
|
||
Figure 7-2. TSS Descriptor for 32-bit TSS
|
||
|
||
31 23 15 7 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÑÍÑÍÑÍÑÍÍÍÍÍÍÍÍÍØÍÑÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º ³ ³ ³ ³A³ LIMIT ³ ³ ³ TYPE ³ º
|
||
º BASE 31..24 ³G³0³0³V³ ³P³ DPL ³ ³ BASE 23..16 º 4
|
||
º ³ ³ ³ ³L³ 19..16 ³ ³ ³0³1³0³B³1³ º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÁÄÁÄÁÄÁÄÄÄÄÄÄÄÄÄÅÄÁÄÄÄÄÄÁÄÁÄÁÄÁÄÁÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º ³ º
|
||
º BASE 15..0 ³ LIMIT 15..0 º 0
|
||
º ³ º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
|
||
7.3 Task Register
|
||
|
||
The task register (TR) identifies the currently executing task by pointing
|
||
to the TSS. Figure 7-3 shows the path by which the processor accesses the
|
||
current TSS.
|
||
|
||
The task register has both a "visible" portion (i.e., can be read and
|
||
changed by instructions) and an "invisible" portion (maintained by the
|
||
processor to correspond to the visible portion; cannot be read by any
|
||
instruction). The selector in the visible portion selects a TSS descriptor
|
||
in the GDT. The processor uses the invisible portion to cache the base and
|
||
limit values from the TSS descriptor. Holding the base and limit in a
|
||
register makes execution of the task more efficient, because the processor
|
||
does not need to repeatedly fetch these values from memory when it
|
||
references the TSS of the current task.
|
||
|
||
The instructions LTR and STR are used to modify and read the visible
|
||
portion of the task register. Both instructions take one operand, a 16-bit
|
||
selector located in memory or in a general register.
|
||
|
||
LTR (Load task register) loads the visible portion of the task register
|
||
with the selector operand, which must select a TSS descriptor in the GDT.
|
||
LTR also loads the invisible portion with information from the TSS
|
||
descriptor selected by the operand. LTR is a privileged instruction; it may
|
||
be executed only when CPL is zero. LTR is generally used during system
|
||
initialization to give an initial value to the task register; thereafter,
|
||
the contents of TR are changed by task switch operations.
|
||
|
||
STR (Store task register) stores the visible portion of the task register
|
||
in a general register or memory word. STR is not privileged.
|
||
|
||
|
||
Figure 7-3. Task Register
|
||
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º º
|
||
º º
|
||
º TASK STATE º
|
||
º SEGMENT ºÄÄÄÄÄÄÄÄÄ¿
|
||
º º ³
|
||
º º ³
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ ³
|
||
16-BIT VISIBLE ³
|
||
REGISTER ³ HIDDEN REGISTER ³
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍ»
|
||
TR º SELECTOR º (BASE) º (LIMT) º
|
||
ÈÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
³
|
||
³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³
|
||
³ GLOBAL DESCRIPTOR TABLE ³ ³
|
||
³ ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ ³ ³
|
||
³ | TSS DESCRIPTOR | ³ ³
|
||
³ ÉÍÍÍÍÍÍËÍÍÍÍÍËÍÍÍÍÍËÍÍÍÍÍÍ» ³ ³
|
||
³ º º º º ÇÄÄÄÙ ³
|
||
³ ÌÍÍÍÍÍÍÊÍÍÍÍÍÎÍÍÍÍÍÊÍÍÍÍÍ͹ ³
|
||
ÀÄÄÄÄÄÄĺ º ÇÄÄÄÄÄÄÄÙ
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
| |
|
||
ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;
|
||
|
||
|
||
7.4 Task Gate Descriptor
|
||
|
||
A task gate descriptor provides an indirect, protected reference to a TSS.
|
||
Figure 7-4 illustrates the format of a task gate.
|
||
|
||
The SELECTOR field of a task gate must refer to a TSS descriptor. The value
|
||
of the RPL in this selector is not used by the processor.
|
||
|
||
The DPL field of a task gate controls the right to use the descriptor to
|
||
cause a task switch. A procedure may not select a task gate descriptor
|
||
unless the maximum of the selector's RPL and the CPL of the procedure is
|
||
numerically less than or equal to the DPL of the descriptor. This constraint
|
||
prevents untrusted procedures from causing a task switch. (Note that when a
|
||
task gate is used, the DPL of the target TSS descriptor is not used for
|
||
privilege checking.)
|
||
|
||
A procedure that has access to a task gate has the power to cause a task
|
||
switch, just as a procedure that has access to a TSS descriptor. The 80386
|
||
has task gates in addition to TSS descriptors to satisfy three needs:
|
||
|
||
1. The need for a task to have a single busy bit. Because the busy-bit
|
||
is stored in the TSS descriptor, each task should have only one such
|
||
descriptor. There may, however, be several task gates that select the
|
||
single TSS descriptor.
|
||
|
||
2. The need to provide selective access to tasks. Task gates fulfill
|
||
this need, because they can reside in LDTs and can have a DPL that is
|
||
different from the TSS descriptor's DPL. A procedure that does not
|
||
have sufficient privilege to use the TSS descriptor in the GDT (which
|
||
usually has a DPL of 0) can still switch to another task if it has
|
||
access to a task gate for that task in its LDT. With task gates,
|
||
systems software can limit the right to cause task switches to
|
||
specific tasks.
|
||
|
||
3. The need for an interrupt or exception to cause a task switch. Task
|
||
gates may also reside in the IDT, making it possible for interrupts
|
||
and exceptions to cause task switching. When interrupt or exception
|
||
vectors to an IDT entry that contains a task gate, the 80386 switches
|
||
to the indicated task. Thus, all tasks in the system can benefit from
|
||
the protection afforded by isolation from interrupt tasks.
|
||
|
||
Figure 7-5 illustrates how both a task gate in an LDT and a task gate in
|
||
the IDT can identify the same task.
|
||
|
||
|
||
Figure 7-4. Task Gate Descriptor
|
||
|
||
31 23 15 7 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÑÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±³ ³ ³ ³±±±±±±±±±±±±±±±±±º
|
||
º±±±±±±±±±±±±(NOT USED)±±±±±±±±±±±±³P³ DPL ³0 0 1 0 1³±±±(NOT USED)±±±±º 4
|
||
º±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±³ ³ ³ ³±±±±±±±±±±±±±±±±±º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÁÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º ³±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±º
|
||
º SELECTOR ³±±±±±±±±±±±±(NOT USED)±±±±±±±±±±±±±º 0
|
||
º ³±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
|
||
Figure 7-5. Task Gate Indirectly Identifies Task
|
||
|
||
LOCAL DESCRIPTOR TABLE INTERRUPT DESCRIPTOR TABLE
|
||
ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸
|
||
| | | |
|
||
| TASK GATE | | TASK GATE |
|
||
ÉÍÍÍÍÍÍÑÍÍÍÍÍÑÍÍÍÍÍÑÍÍÍÍÍÍ» ÉÍÍÍÍÍÍÑÍÍÍÍÍÑÍÍÍÍÍÑÍÍÍÍÍÍ»
|
||
º ³ ³ ³ º º ³ ³ ³ º
|
||
ÇÄÄÄÄÄÄÁÄÄÄÄÄÅÄÄÄÄÄÁÄÄÄÄÄĶ ÇÄÄÄÄÄÄÁÄÄÄÄÄÅÄÄÄÄÄÁÄÄÄÄÄĶ
|
||
ÚÄĶ ³ º ÚÄĶ ³ º
|
||
³ ÈÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍͼ ³ ÈÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
³ | | ³ | |
|
||
³ | | ³ | |
|
||
³ ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ; ³ ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;
|
||
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
||
³ ³ GLOBAL DESCRIPTOR TABLE
|
||
³ ³ ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸
|
||
³ ³ | |
|
||
³ ³ | TASK DESCRIPTOR |
|
||
³ ³ ÉÍÍÍÍÍÍÑÍÍÍÍÍÑÍÍÍÍÍÑÍÍÍÍÍÍ»
|
||
³ ³ º ³ ³ ³ º
|
||
³ ÀÄÇÄÄÄÄÄÄÁÄÄÄÄÄÅÄÄÄÄÄÁÄÄÄÄÄĶ
|
||
ÀÄÄÄĺ ³ ÇÄÄ¿
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍͼ ³
|
||
| | ³
|
||
| | ³
|
||
ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ; ³
|
||
³
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» ³
|
||
º º ³
|
||
º º ³
|
||
º º ³
|
||
º TASK STATE º ³
|
||
º SEGMENT º ³
|
||
º º ³
|
||
º º ³
|
||
º º ³
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼÄÙ
|
||
|
||
|
||
7.5 Task Switching
|
||
|
||
The 80386 switches execution to another task in any of four cases:
|
||
|
||
1. The current task executes a JMP or CALL that refers to a TSS
|
||
descriptor.
|
||
|
||
2. The current task executes a JMP or CALL that refers to a task gate.
|
||
|
||
3. An interrupt or exception vectors to a task gate in the IDT.
|
||
|
||
4. The current task executes an IRET when the NT flag is set.
|
||
|
||
JMP, CALL, IRET, interrupts, and exceptions are all ordinary mechanisms of
|
||
the 80386 that can be used in circumstances that do not require a task
|
||
switch. Either the type of descriptor referenced or the NT (nested task) bit
|
||
in the flag word distinguishes between the standard mechanism and the
|
||
variant that causes a task switch.
|
||
|
||
To cause a task switch, a JMP or CALL instruction can refer either to a TSS
|
||
descriptor or to a task gate. The effect is the same in either case: the
|
||
80386 switches to the indicated task.
|
||
|
||
An exception or interrupt causes a task switch when it vectors to a task
|
||
gate in the IDT. If it vectors to an interrupt or trap gate in the IDT, a
|
||
task switch does not occur. Refer to Chapter 9 for more information on the
|
||
interrupt mechanism.
|
||
|
||
Whether invoked as a task or as a procedure of the interrupted task, an
|
||
interrupt handler always returns control to the interrupted procedure in the
|
||
interrupted task. If the NT flag is set, however, the handler is an
|
||
interrupt task, and the IRET switches back to the interrupted task.
|
||
|
||
A task switching operation involves these steps:
|
||
|
||
1. Checking that the current task is allowed to switch to the designated
|
||
task. Data-access privilege rules apply in the case of JMP or CALL
|
||
instructions. The DPL of the TSS descriptor or task gate must be less
|
||
than or equal to the maximum of CPL and the RPL of the gate selector.
|
||
Exceptions, interrupts, and IRETs are permitted to switch tasks
|
||
regardless of the DPL of the target task gate or TSS descriptor.
|
||
|
||
2. Checking that the TSS descriptor of the new task is marked present
|
||
and has a valid limit. Any errors up to this point occur in the
|
||
context of the outgoing task. Errors are restartable and can be
|
||
handled in a way that is transparent to applications procedures.
|
||
|
||
3. Saving the state of the current task. The processor finds the base
|
||
address of the current TSS cached in the task register. It copies the
|
||
registers into the current TSS (EAX, ECX, EDX, EBX, ESP, EBP, ESI,
|
||
EDI, ES, CS, SS, DS, FS, GS, and the flag register). The EIP field of
|
||
the TSS points to the instruction after the one that caused the task
|
||
switch.
|
||
|
||
4. Loading the task register with the selector of the incoming task's
|
||
TSS descriptor, marking the incoming task's TSS descriptor as busy,
|
||
and setting the TS (task switched) bit of the MSW. The selector is
|
||
either the operand of a control transfer instruction or is taken from
|
||
a task gate.
|
||
|
||
5. Loading the incoming task's state from its TSS and resuming
|
||
execution. The registers loaded are the LDT register; the flag
|
||
register; the general registers EIP, EAX, ECX, EDX, EBX, ESP, EBP,
|
||
ESI, EDI; the segment registers ES, CS, SS, DS, FS, and GS; and PDBR.
|
||
Any errors detected in this step occur in the context of the incoming
|
||
task. To an exception handler, it appears that the first instruction
|
||
of the new task has not yet executed.
|
||
|
||
Note that the state of the outgoing task is always saved when a task switch
|
||
occurs. If execution of that task is resumed, it starts after the
|
||
instruction that caused the task switch. The registers are restored to the
|
||
values they held when the task stopped executing.
|
||
|
||
Every task switch sets the TS (task switched) bit in the MSW (machine
|
||
status word). The TS flag is useful to systems software when a coprocessor
|
||
(such as a numerics coprocessor) is present. The TS bit signals that the
|
||
context of the coprocessor may not correspond to the current 80386 task.
|
||
Chapter 11 discusses the TS bit and coprocessors in more detail.
|
||
|
||
Exception handlers that field task-switch exceptions in the incoming task
|
||
(exceptions due to tests 4 thru 16 of Table 7-1) should be cautious about
|
||
taking any action that might load the selector that caused the exception.
|
||
Such an action will probably cause another exception, unless the exception
|
||
handler first examines the selector and fixes any potential problem.
|
||
|
||
The privilege level at which execution resumes in the incoming task is
|
||
neither restricted nor affected by the privilege level at which the outgoing
|
||
task was executing. Because the tasks are isolated by their separate address
|
||
spaces and TSSs and because privilege rules can be used to prevent improper
|
||
access to a TSS, no privilege rules are needed to constrain the relation
|
||
between the CPLs of the tasks. The new task begins executing at the
|
||
privilege level indicated by the RPL of the CS selector value that is loaded
|
||
from the TSS.
|
||
|
||
|
||
Table 7-1. Checks Made during a Task Switch
|
||
|
||
|
||
Test Test Description Exception
|
||
NP = Segment-not-present exception, GP = General protection fault, TS =
|
||
Invalid TSS, SF = Stack fault Error Code Selects
|
||
|
||
1 Incoming TSS descriptor is NP Incoming TSS
|
||
present
|
||
2 Incoming TSS descriptor is GP Incoming TSS
|
||
marked not-busy
|
||
3 Limit of incoming TSS is TS Incoming TSS
|
||
greater than or equal to 103
|
||
|
||
ÄÄ All register and selector values are loaded ÄÄ
|
||
|
||
4 LDT selector of incoming TS Incoming TSS
|
||
task is valid
|
||
5 LDT of incoming task is TS Incoming TSS
|
||
present
|
||
6 CS selector is valid
|
||
Validity tests of a selector check that the selector is in the proper
|
||
table (eg., the LDT selector refers to the GDT), lies within the bounds of
|
||
the table, and refers to the proper type of descriptor (e.g., the LDT
|
||
selector refers to an LDT descriptor). TS Code segment
|
||
7 Code segment is present NP Code segment
|
||
8 Code segment DPL matches TS Code segment
|
||
CS RPL
|
||
9 Stack segment is valid
|
||
Validity tests of a selector check that the selector is in the proper
|
||
table (eg., the LDT selector refers to the GDT), lies within the bounds of
|
||
the table, and refers to the proper type of descriptor (e.g., the LDT
|
||
selector refers to an LDT descriptor). GP Stack segment
|
||
10 Stack segment is present SF Stack segment
|
||
11 Stack segment DPL = CPL SF Stack segment
|
||
12 Stack-selector RPL = CPL GP Stack segment
|
||
13 DS, ES, FS, GS selectors are GP Segment
|
||
valid
|
||
Validity tests of a selector check that the selector is in the proper
|
||
table (eg., the LDT selector refers to the GDT), lies within the bounds of
|
||
the table, and refers to the proper type of descriptor (e.g., the LDT
|
||
selector refers to an LDT descriptor).
|
||
|
||
|
||
14 DS, ES, FS, GS segments GP Segment
|
||
are readable
|
||
15 DS, ES, FS, GS segments NP Segment
|
||
are present
|
||
16 DS, ES, FS, GS segment DPL GP Segment
|
||
ò CPL (unless these are
|
||
conforming segments)
|
||
|
||
|
||
7.6 Task Linking
|
||
|
||
The back-link field of the TSS and the NT (nested task) bit of the flag
|
||
word together allow the 80386 to automatically return to a task that CALLed
|
||
another task or was interrupted by another task. When a CALL instruction, an
|
||
interrupt instruction, an external interrupt, or an exception causes a
|
||
switch to a new task, the 80386 automatically fills the back-link of the new
|
||
TSS with the selector of the outgoing task's TSS and, at the same time,
|
||
sets the NT bit in the new task's flag register. The NT flag indicates
|
||
whether the back-link field is valid. The new task releases control by
|
||
executing an IRET instruction. When interpreting an IRET, the 80386 examines
|
||
the NT flag. If NT is set, the 80386 switches back to the task selected by
|
||
the back-link field. Table 7-2 summarizes the uses of these fields.
|
||
|
||
|
||
Table 7-2. Effect of Task Switch on BUSY, NT, and Back-Link
|
||
|
||
Affected Field Effect of JMP Effect of Effect of
|
||
Instruction CALL Instruction IRET Instruction
|
||
|
||
Busy bit of Set, must be Set, must be 0 Unchanged,
|
||
incoming task 0 before before must be set
|
||
|
||
Busy bit of Cleared Unchanged Cleared
|
||
outgoing task (already set)
|
||
|
||
NT bit of Cleared Set Unchanged
|
||
incoming task
|
||
|
||
NT bit of Unchanged Unchanged Cleared
|
||
outgoing task
|
||
|
||
Back-link of Unchanged Set to outgoing Unchanged
|
||
incoming task TSS selector
|
||
|
||
Back-link of Unchanged Unchanged Unchanged
|
||
outgoing task
|
||
|
||
|
||
7.6.1 Busy Bit Prevents Loops
|
||
|
||
The B-bit (busy bit) of the TSS descriptor ensures the integrity of the
|
||
back-link. A chain of back-links may grow to any length as interrupt tasks
|
||
interrupt other interrupt tasks or as called tasks call other tasks. The
|
||
busy bit ensures that the CPU can detect any attempt to create a loop. A
|
||
loop would indicate an attempt to reenter a task that is already busy;
|
||
however, the TSS is not a reentrable resource.
|
||
|
||
The processor uses the busy bit as follows:
|
||
|
||
1. When switching to a task, the processor automatically sets the busy
|
||
bit of the new task.
|
||
|
||
2. When switching from a task, the processor automatically clears the
|
||
busy bit of the old task if that task is not to be placed on the
|
||
back-link chain (i.e., the instruction causing the task switch is JMP
|
||
or IRET). If the task is placed on the back-link chain, its busy bit
|
||
remains set.
|
||
|
||
3. When switching to a task, the processor signals an exception if the
|
||
busy bit of the new task is already set.
|
||
|
||
By these actions, the processor prevents a task from switching to itself or
|
||
to any task that is on a back-link chain, thereby preventing invalid reentry
|
||
into a task.
|
||
|
||
The busy bit is effective even in multiprocessor configurations, because
|
||
the processor automatically asserts a bus lock when it sets or clears the
|
||
busy bit. This action ensures that two processors do not invoke the same
|
||
task at the same time. (Refer to Chapter 11 for more on multiprocessing.)
|
||
|
||
|
||
7.6.2 Modifying Task Linkages
|
||
|
||
Any modification of the linkage order of tasks should be accomplished only
|
||
by software that can be trusted to correctly update the back-link and the
|
||
busy-bit. Such changes may be needed to resume an interrupted task before
|
||
the task that interrupted it. Trusted software that removes a task from the
|
||
back-link chain must follow one of the following policies:
|
||
|
||
1. First change the back-link field in the TSS of the interrupting task,
|
||
then clear the busy-bit in the TSS descriptor of the task removed from
|
||
the list.
|
||
|
||
2. Ensure that no interrupts occur between updating the back-link chain
|
||
and the busy bit.
|
||
|
||
|
||
7.7 Task Address Space
|
||
|
||
The LDT selector and PDBR fields of the TSS give software systems designers
|
||
flexibility in utilization of segment and page mapping features of the
|
||
80386. By appropriate choice of the segment and page mappings for each task,
|
||
tasks may share address spaces, may have address spaces that are largely
|
||
distinct from one another, or may have any degree of sharing between these
|
||
two extremes.
|
||
|
||
The ability for tasks to have distinct address spaces is an important
|
||
aspect of 80386 protection. A module in one task cannot interfere with a
|
||
module in another task if the modules do not have access to the same address
|
||
spaces. The flexible memory management features of the 80386 allow systems
|
||
designers to assign areas of shared address space to those modules of
|
||
different tasks that are designed to cooperate with each other.
|
||
|
||
|
||
7.7.1 Task Linear-to-Physical Space Mapping
|
||
|
||
The choices for arranging the linear-to-physical mappings of tasks fall
|
||
into two general classes:
|
||
|
||
1. One linear-to-physical mapping shared among all tasks.
|
||
|
||
When paging is not enabled, this is the only possibility. Without page
|
||
tables, all linear addresses map to the same physical addresses.
|
||
|
||
When paging is enabled, this style of linear-to-physical mapping
|
||
results from using one page directory for all tasks. The linear space
|
||
utilized may exceed the physical space available if the operating
|
||
system also implements page-level virtual memory.
|
||
|
||
2. Several partially overlapping linear-to-physical mappings.
|
||
|
||
This style is implemented by using a different page directory for each
|
||
task. Because the PDBR (page directory base register) is loaded from
|
||
the TSS with each task switch, each task may have a different page
|
||
directory.
|
||
|
||
In theory, the linear address spaces of different tasks may map to
|
||
completely distinct physical addresses. If the entries of different page
|
||
directories point to different page tables and the page tables point to
|
||
different pages of physical memory, then the tasks do not share any physical
|
||
addresses.
|
||
|
||
In practice, some portion of the linear address spaces of all tasks must
|
||
map to the same physical addresses. The task state segments must lie in a
|
||
common space so that the mapping of TSS addresses does not change while the
|
||
processor is reading and updating the TSSs during a task switch. The linear
|
||
space mapped by the GDT should also be mapped to a common physical space;
|
||
otherwise, the purpose of the GDT is defeated. Figure 7-6 shows how the
|
||
linear spaces of two tasks can overlap in the physical space by sharing
|
||
page tables.
|
||
|
||
|
||
7.7.2 Task Logical Address Space
|
||
|
||
By itself, a common linear-to-physical space mapping does not enable
|
||
sharing of data among tasks. To share data, tasks must also have a common
|
||
logical-to-linear space mapping; i.e., they must also have access to
|
||
descriptors that point into a shared linear address space. There are three
|
||
ways to create common logical-to-physical address-space mappings:
|
||
|
||
1. Via the GDT. All tasks have access to the descriptors in the GDT. If
|
||
those descriptors point into a linear-address space that is mapped to
|
||
a common physical-address space for all tasks, then the tasks can
|
||
share data and instructions.
|
||
|
||
2. By sharing LDTs. Two or more tasks can use the same LDT if the LDT
|
||
selectors in their TSSs select the same LDT segment. Those
|
||
LDT-resident descriptors that point into a linear space that is mapped
|
||
to a common physical space permit the tasks to share physical memory.
|
||
This method of sharing is more selective than sharing by the GDT; the
|
||
sharing can be limited to specific tasks. Other tasks in the system
|
||
may have different LDTs that do not give them access to the shared
|
||
areas.
|
||
|
||
3. By descriptor aliases in LDTs. It is possible for certain descriptors
|
||
of different LDTs to point to the same linear address space. If that
|
||
linear address space is mapped to the same physical space by the page
|
||
mapping of the tasks involved, these descriptors permit the tasks to
|
||
share the common space. Such descriptors are commonly called
|
||
"aliases". This method of sharing is even more selective than the
|
||
prior two; other descriptors in the LDTs may point to distinct linear
|
||
addresses or to linear addresses that are not shared.
|
||
|
||
|
||
Figure 7-6. Partially-Overlapping Linear Spaces
|
||
|
||
TSSs PAGE FRAMES
|
||
ÉÍÍÍÍÍÍÍÍÍÍ»
|
||
TASK A TSS PAGE DIRECTORIES PAGE TABLES º TASK A º
|
||
ÉÍÍÍÍÍÍÍÍÍÍ» ÉÍÍÍÍÍÍÍÍÍÍÍ» ÉÍÍÍÍÍÍÍÍÍÍÍ» Úĺ PAGE º
|
||
º º º º º º ³ ÈÍÍÍÍÍÍÍÍÍͼ
|
||
º º ÌÍÍÍÍÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍÍÍÍ͹ ³ ÉÍÍÍÍÍÍÍÍÍÍ»
|
||
º º º º º PTE ÇÄÄÙ º TASK A º
|
||
º º ÌÍÍÍÍÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍÍÍÍ͹ Úĺ PAGE º
|
||
º º º º º PTE ÇÄÄÙ ÈÍÍÍÍÍÍÍÍÍͼ
|
||
ÌÍÍÍÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍÍÍÍ͹ ÉÍÍÍÍÍÍÍÍÍÍ»
|
||
º PDBR ÇÄÄÄĺ PDE ÇÄÄÄĺ PTE ÇÄÄ¿ º TASK A º
|
||
ÌÍÍÍÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍÍÍÍ͹ ÈÍÍÍÍÍÍÍÍÍÍͼ Àĺ PAGE º
|
||
º º º PDE ÇÄÄ¿ SHARED PT ÈÍÍÍÍÍÍÍÍÍͼ
|
||
ÈÍÍÍÍÍÍÍÍÍͼ ÈÍÍÍÍÍÍÍÍÍÍͼ ³ ÉÍÍÍÍÍÍÍÍÍÍÍ» ÉÍÍÍÍÍÍÍÍÍÍ»
|
||
³ º º º SHARED º
|
||
³ ÌÍÍÍÍÍÍÍÍÍÍ͹ Úĺ PAGE º
|
||
³ º º ³ ÈÍÍÍÍÍÍÍÍÍͼ
|
||
³ ÌÍÍÍÍÍÍÍÍÍÍ͹ ³ ÉÍÍÍÍÍÍÍÍÍÍ»
|
||
³ º PTE ÇÄÄÙ º SHARED º
|
||
³ ÌÍÍÍÍÍÍÍÍÍÍ͹ Úĺ PAGE º
|
||
Ãĺ PTE ÇÄÄÙ ÈÍÍÍÍÍÍÍÍÍͼ
|
||
TASK B TSS ³ ÈÍÍÍÍÍÍÍÍÍÍͼ ÉÍÍÍÍÍÍÍÍÍÍ»
|
||
ÉÍÍÍÍÍÍÍÍÍÍ» ÉÍÍÍÍÍÍÍÍÍÍÍ» ³ º TASK B º
|
||
º º º º ³ ÚÄĺ PAGE º
|
||
º º ÌÍÍÍÍÍÍÍÍÍÍ͹ ³ ÉÍÍÍÍÍÍÍÍÍÍÍ» ³ ÈÍÍÍÍÍÍÍÍÍͼ
|
||
º º º º ³ º º ³ ÉÍÍÍÍÍÍÍÍÍÍ»
|
||
º º ÌÍÍÍÍÍÍÍÍÍÍ͹ ³ ÌÍÍÍÍÍÍÍÍÍÍ͹ ³ º TASK B º
|
||
º º º º ³ º º ³ Úº PAGE º
|
||
ÌÍÍÍÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍÍÍÍ͹ ³ ÌÍÍÍÍÍÍÍÍÍÍ͹ ³ ³ ÈÍÍÍÍÍÍÍÍÍͼ
|
||
º PDBR ÇÄÄÄĺ PDE ÇÄÄÙ º PTE ÇÄÙ ³ PAGE FRAMES
|
||
ÌÍÍÍÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍÍÍÍ͹ ³
|
||
º º º PDE ÇÄÄÄĺ PTE ÇÄÄÄÙ
|
||
ÈÍÍÍÍÍÍÍÍÍͼ ÈÍÍÍÍÍÍÍÍÍÍͼ ÈÍÍÍÍÍÍÍÍÍÍͼ
|
||
TSSs PAGE DIRECTORIES PAGE TABLES
|
||
|
||
|
||
Chapter 8 Input/Output
|
||
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
This chapter presents the I/O features of the 80386 from the following
|
||
perspectives:
|
||
|
||
þ Methods of addressing I/O ports
|
||
|
||
þ Instructions that cause I/O operations
|
||
|
||
þ Protection as it applies to the use of I/O instructions and I/O port
|
||
addresses.
|
||
|
||
|
||
8.1 I/O Addressing
|
||
|
||
The 80386 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)
|
||
|
||
þ By means of memory-mapped I/O (using general-purpose operand
|
||
manipulationinstructions).
|
||
|
||
|
||
8.1.1 I/O Address Space
|
||
|
||
The 80386 provides a separate I/O address space, distinct from physical
|
||
memory, that can be used to address the input/output ports that are used for
|
||
external 16 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; and four consecutive 8-bit ports can be treated
|
||
as a 32-bit port. Thus, the I/O address space can accommodate up to 64K
|
||
8-bit ports, up to 32K 16-bit ports, or up to 16K 32-bit ports.
|
||
|
||
The program can specify the address of the port in two ways. Using an
|
||
immediate byte constant, the program can specify:
|
||
|
||
þ 256 8-bit ports numbered 0 through 255.
|
||
þ 128 16-bit ports numbered 0, 2, 4, . . . , 252, 254.
|
||
þ 64 32-bit ports numbered 0, 4, 8, . . . , 248, 252.
|
||
|
||
Using a value in DX, the program can specify:
|
||
|
||
þ 8-bit ports numbered 0 through 65535
|
||
þ 16-bit ports numbered 0, 2, 4, . . . , 65532, 65534
|
||
þ 32-bit ports numbered 0, 4, 8, . . . , 65528, 65532
|
||
|
||
The 80386 can transfer 32, 16, or 8 bits at a time to a device located in
|
||
the I/O space. Like doublewords in memory, 32-bit ports should be aligned at
|
||
addresses evenly divisible by four so that the 32 bits can be transferred in
|
||
a single bus access. Like words in memory, 16-bit ports should be aligned at
|
||
even-numbered addresses so that the 16 bits can be transferred in a single
|
||
bus access. An 8-bit port may be located at either an even or odd address.
|
||
|
||
The instructions IN and OUT move data between a register and a port in the
|
||
I/O address space. The instructions INS and OUTS move strings of data
|
||
between the memory address space and ports in the I/O address space.
|
||
|
||
|
||
8.1.2 Memory-Mapped I/O
|
||
|
||
I/O devices also may be placed in the 80386 memory address space. As 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
|
||
8-1). Memory-mapped I/O performed via the full instruction set maintains
|
||
the full complement of addressing modes for selecting the desired I/O
|
||
device (e.g., direct address, indirect address, base register, index
|
||
register, scaling).
|
||
|
||
Memory-mapped I/O, like any other memory reference, is subject to access
|
||
protection and control when executing in protected mode. Refer to Chapter 6
|
||
for a discussion of memory protection.
|
||
|
||
|
||
8.2 I/O Instructions
|
||
|
||
The I/O instructions of the 80386 provide access to the processor's I/O
|
||
ports for the transfer of data to and from peripheral devices. These
|
||
instructions have as one operand the address of a port in the I/O address
|
||
space. There are two classes of I/O instruction:
|
||
|
||
1. Those that transfer a single item (byte, word, or doubleword) located
|
||
in a register.
|
||
|
||
2. Those that transfer strings of items (strings of bytes, words, or
|
||
doublewords) located in memory. These are known as "string I/O
|
||
instructions" or "block I/O instructions".
|
||
|
||
|
||
8.2.1 Register I/O Instructions
|
||
|
||
The I/O instructions IN and OUT are provided to move data between I/O ports
|
||
and the EAX (32-bit I/O), the AX (16-bit I/O), or AL (8-bit I/O) general
|
||
registers. IN and OUT instructions address I/O ports either directly, with
|
||
the address of one of up to 256 port addresses coded in the instruction, or
|
||
indirectly via the DX register to one of up to 64K port addresses.
|
||
|
||
IN (Input from Port) transfers a byte, word, or doubleword from an input
|
||
port to AL, AX, or EAX. If a program specifies AL with the IN instruction,
|
||
the processor transfers 8 bits from the selected port to AL. If a program
|
||
specifies AX with the IN instruction, the processor transfers 16 bits from
|
||
the port to AX. If a program specifies EAX with the IN instruction, the
|
||
processor transfers 32 bits from the port to EAX.
|
||
|
||
OUT (Output to Port) transfers a byte, word, or doubleword to an output
|
||
port from AL, AX, or EAX. The program can specify the number of the port
|
||
using the same methods as the IN instruction.
|
||
|
||
|
||
Figure 8-1. Memory-Mapped I/O
|
||
|
||
MEMORY
|
||
ADDRESS SPACE I/O DEVICE 1
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º º º INTERNAL REGISTER º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ Ä Ä Ä Ä Ä Ä Ä Ä ÄºÄÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» º
|
||
º º º º º º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ Ä Ä Ä Ä Ä Ä Ä Ä ÄºÄÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ º
|
||
º º ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
º º
|
||
º º
|
||
º º
|
||
º º I/O DEVICE 2
|
||
º º ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º º º INTERNAL REGISTER º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ Ä Ä Ä Ä Ä Ä Ä Ä ÄºÄÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» º
|
||
º º º º º º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ Ä Ä Ä Ä Ä Ä Ä Ä ÄºÄÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ º
|
||
º º ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
|
||
8.2.2 Block I/O Instructions
|
||
|
||
The block (or string) I/O instructions INS and OUTS move blocks of data
|
||
between I/O ports and memory space. Block I/O instructions use the DX
|
||
register to specify the address of a port in the I/O address space. INS and
|
||
OUTS use DX to specify:
|
||
|
||
þ 8-bit ports numbered 0 through 65535
|
||
þ 16-bit ports numbered 0, 2, 4, . . . , 65532, 65534
|
||
þ 32-bit ports numbered 0, 4, 8, . . . , 65528, 65532
|
||
|
||
Block I/O instructions use either SI or DI to designate the source or
|
||
destination memory address. For each transfer, SI or DI are automatically
|
||
either incremented or decremented as specified by the direction bit in the
|
||
flags register.
|
||
|
||
INS and OUTS, when used with repeat prefixes, cause block input or output
|
||
operations. REP, the repeat prefix, modifies INS and OUTS to provide a means
|
||
of transferring blocks of data between an I/O port and memory. These block
|
||
I/O instructions are string primitives (refer also to Chapter 3 for more on
|
||
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.
|
||
|
||
The string I/O primitives can operate on byte strings, word strings, or
|
||
doubleword strings. After each transfer, the memory address in ESI or EDI is
|
||
updated by 1 for byte operands, by 2 for word operands, or by 4 for
|
||
doubleword operands. The value in the direction flag (DF) determines whether
|
||
the processor automatically increments ESI or EDI (DF=0) or whether it
|
||
automatically decrements these registers (DF=1).
|
||
|
||
INS (Input String from Port) transfers a byte or a word string element from
|
||
an input port to memory. The mnemonics INSB, INSW, and INSD are variants
|
||
that explicitly specify the size of the operand. If a program specifies
|
||
INSB, the processor transfers 8 bits from the selected port to the memory
|
||
location indicated by ES:EDI. If a program specifies INSW, the processor
|
||
transfers 16 bits from the port to the memory location indicated by ES:EDI.
|
||
If a program specifies INSD, the processor transfers 32 bits from the port
|
||
to the memory location indicated by ES:EDI. 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.
|
||
|
||
OUTS (Output String to Port) transfers a byte, word, or doubleword string
|
||
element to an output port from memory. The mnemonics OUTSB, OUTSW, and OUTSD
|
||
are variants that explicitly specify the size of the operand. If a program
|
||
specifies OUTSB, the processor transfers 8 bits from the memory location
|
||
indicated by ES:EDI to the the selected port. If a program specifies OUTSW,
|
||
the processor transfers 16 bits from the memory location indicated by ES:EDI
|
||
to the the selected port. If a program specifies OUTSD, the processor
|
||
transfers 32 bits from the memory location indicated by ES:EDI to the the
|
||
selected port. Combined with the REP prefix, OUTS moves a block of
|
||
information from a series of consecutive memory locations indicated by
|
||
DS:ESI to an output port.
|
||
|
||
|
||
8.3 Protection and I/O
|
||
|
||
Two mechanisms provide protection for I/O functions:
|
||
|
||
1. The IOPL field in the EFLAGS register defines the right to use
|
||
I/O-related instructions.
|
||
|
||
2. The I/O permission bit map of a 80386 TSS segment defines the right
|
||
to use ports in the I/O address space.
|
||
|
||
These mechanisms operate only in protected mode, including virtual 8086
|
||
mode; they do not operate in real mode. In real mode, there is no protection
|
||
of the I/O space; any procedure can execute I/O instructions, and any I/O
|
||
port can be addressed by the I/O instructions.
|
||
|
||
|
||
8.3.1 I/O Privilege Level
|
||
|
||
Instructions that deal with I/O need to be restricted but also need to be
|
||
executed by procedures executing at privilege levels other than zero. For
|
||
this reason, the processor uses two bits of the flags register to store the
|
||
I/O privilege level (IOPL). The IOPL defines the privilege level
|
||
needed to execute I/O-related instructions.
|
||
|
||
The following instructions can be executed only if CPL ó IOPL:
|
||
|
||
IN ÄÄ Input
|
||
INS ÄÄ Input String
|
||
OUT ÄÄ Output
|
||
OUTS ÄÄ Output String
|
||
CLI ÄÄ Clear Interrupt-Enable Flag
|
||
STI ÄÄ Set Interrupt-Enable
|
||
|
||
These instructions are called "sensitive" instructions, because they are
|
||
sensitive to IOPL.
|
||
|
||
To use sensitive instructions, a procedure must execute at a privilege
|
||
level at least as privileged as that specified by the IOPL (CPL ó IOPL). Any
|
||
attempt by a less privileged procedure to use a sensitive instruction
|
||
results in a general protection exception.
|
||
|
||
Because each task has its own unique copy of the flags register, each task
|
||
can have a different IOPL. A task whose primary function is to perform I/O
|
||
(a device driver) can benefit from having an IOPL of three, thereby
|
||
permitting all procedures of the task to performI/O. Other tasks typically
|
||
have IOPL set to zero or one, reserving the right to perform I/O
|
||
instructions for the most privileged procedures.
|
||
|
||
A task can change IOPL only with the POPF instruction; however, such
|
||
changes are privileged. No procedure may alter IOPL (the I/O privilege level
|
||
in the flag register) unless the procedure is executing at privilege level
|
||
0. An attempt by a less privileged procedure to alter IOPL does not result
|
||
in an exception; IOPL simply remains unaltered.
|
||
|
||
The POPF instruction may be used in addition to CLI and STI to alter the
|
||
interrupt-enable flag (IF); however, changes to IF by POPF are
|
||
IOPL-sensitive. A procedure may alter IF with a POPF instruction only when
|
||
executing at a level that is at least as privileged as IOPL. An attempt by a
|
||
less privileged procedure to alter IF in this manner does not result in an
|
||
exception; IF simply remains unaltered.
|
||
|
||
|
||
8.3.2 I/O Permission Bit Map
|
||
|
||
The I/O instructions that directly refer to addresses in the processor's
|
||
I/O space are IN, INS, OUT, OUTS. The 80386 has the ability to selectively
|
||
trap references to specific I/O addresses. The structure that enables
|
||
selective trapping is the I/O Permission Bit Map in the TSS segment (see
|
||
Figure 8-2). The I/O permission map is a bit vector. The size of the map
|
||
and its location in the TSS segment are variable. The processor locates the
|
||
I/O permission map by means of the I/O map base field in the fixed portion
|
||
of the TSS. The I/O map base field is 16 bits wide and contains the offset
|
||
of the beginning of the I/O permission map. The upper limit of the I/O
|
||
permission map is the same as the limit of the TSS segment.
|
||
|
||
In protected mode, when it encounters an I/O instruction (IN, INS, OUT, or
|
||
OUTS), the processor first checks whether CPL ó IOPL. If this condition is
|
||
true, the I/O operation may proceed. If not true, the processor checks the
|
||
I/O permission map. (In virtual 8086 mode, the processor consults the map
|
||
without regard for IOPL. Refer to Chapter 15.)
|
||
|
||
Each bit in the map corresponds to an I/O port byte address; for example,
|
||
the bit for port 41 is found at I/O map base + 5, bit offset 1. The
|
||
processor tests all the bits that correspond to the I/O addresses spanned by
|
||
an I/O operation; for example, a doubleword operation tests four bits
|
||
corresponding to four adjacent byte addresses. If any tested bit is set,
|
||
the processor signals a general protection exception. If all the tested bits
|
||
are zero, the I/O operation may proceed.
|
||
|
||
It is not necessary for the I/O permission map to represent all the I/O
|
||
addresses. I/O addresses not spanned by the map are treated as if they had
|
||
one bits in the map. For example, if TSS limit is equal to I/O map base +
|
||
31, the first 256 I/O ports are mapped; I/O operations on any port greater
|
||
than 255 cause an exception.
|
||
|
||
If I/O map base is greater than or equal to TSS limit, the TSS segment has
|
||
no I/O permission map, and all I/O instructions in the 80386 program cause
|
||
exceptions when CPL > IOPL.
|
||
|
||
Because the I/O permission map is in the TSS segment, different tasks can
|
||
have different maps. Thus, the operating system can allocate ports to a task
|
||
by changing the I/O permission map in the task's TSS.
|
||
|
||
|
||
Figure 8-2. I/O Address Bit Map
|
||
|
||
TSS SEGMEMT
|
||
|
||
31 23 15 7 0
|
||
ÉÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍ»
|
||
LIMITÄÄĺ º
|
||
º Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä º
|
||
|
||
I/O PERMISSION BIT MAP
|
||
|
||
º Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä º
|
||
ÚÄÄÄĺ º
|
||
³ ÇÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄĶ
|
||
³
|
||
³
|
||
³
|
||
³ ÇÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄĶ
|
||
ÀÄÄÄÄĶ I/O MAP BASE ³uuuuuuuu uuuuuuuTº64
|
||
ÇÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄĶ
|
||
º00000000 00000000³ LOT º60
|
||
ÇÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄĶ
|
||
º00000000 00000000³ GS º5C
|
||
ÇÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄĶ
|
||
º º58
|
||
|
||
|
||
|
||
º º4
|
||
ÇÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄĶ
|
||
º00000000 00000000³ TSS BACK LINK º0
|
||
ÈÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍͼ
|
||
|
||
|
||
Chapter 9 Exceptions and Interrupts
|
||
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
Interrupts and exceptions are special kinds of control transfer; they work
|
||
somewhat like unprogrammed CALLs. They alter the normal program flow to
|
||
handle external events or to report errors or exceptional conditions. The
|
||
difference between interrupts and exceptions is that interrupts are used to
|
||
handle asynchronous events external to the processor, but exceptions handle
|
||
conditions detected by the processor itself in the course of executing
|
||
instructions.
|
||
|
||
There are two sources for external interrupts and two sources for
|
||
exceptions:
|
||
|
||
1. Interrupts
|
||
|
||
þ Maskable interrupts, which are signalled via the INTR pin.
|
||
|
||
þ Nonmaskable interrupts, which are signalled via the NMI
|
||
(Non-Maskable Interrupt) pin.
|
||
|
||
2. Exceptions
|
||
|
||
þ Processor detected. These are further classified as faults, traps,
|
||
and aborts.
|
||
|
||
þ Programmed. The instructions INTO, INT 3, INT n, and BOUND can
|
||
trigger exceptions. These instructions are often called "software
|
||
interrupts", but the processor handles them as exceptions.
|
||
|
||
This chapter explains the features that the 80386 offers for controlling
|
||
and responding to interrupts when it is executing in protected mode.
|
||
|
||
|
||
9.1 Identifying Interrupts
|
||
|
||
The processor associates an identifying number with each different type of
|
||
interrupt or exception.
|
||
|
||
The NMI and the exceptions recognized by the processor are assigned
|
||
predetermined identifiers in the range 0 through 31. Not all of these
|
||
numbers are currently used by the 80386; unassigned identifiers in this
|
||
range are reserved by Intel for possible future expansion.
|
||
|
||
The identifiers of the maskable interrupts are determined by external
|
||
interrupt controllers (such as Intel's 8259A Programmable Interrupt
|
||
Controller) and communicated to the processor during the processor's
|
||
interrupt-acknowledge sequence. The numbers assigned by an 8259A PIC can be
|
||
specified by software. Any numbers in the range 32 through 255 can be used.
|
||
Table 9-1 shows the assignment of interrupt and exception identifiers.
|
||
|
||
Exceptions are classified as faults, traps, or aborts depending on the way
|
||
they are reported and whether restart of the instruction that caused the
|
||
exception is supported.
|
||
|
||
Faults Faults are exceptions that are reported "before" the
|
||
instruction causingthe exception. Faults are either detected before
|
||
the instruction begins to execute, or during execution of the
|
||
instruction. If detected during the instruction, the fault is
|
||
reported with the machine restored to a state that permits the
|
||
instruction to be restarted.
|
||
|
||
Traps A trap is an exception that is reported at the instruction
|
||
boundary immediately after the instruction in which the
|
||
exception was detected.
|
||
|
||
Aborts An abort is an exception that permits neither precise location
|
||
of the instruction causing the exception nor restart of the program
|
||
that caused the exception. Aborts are used to report severe errors,
|
||
such as hardware errors and inconsistent or illegal values in system
|
||
tables.
|
||
|
||
|
||
Table 9-1. Interrupt and Exception ID Assignments
|
||
|
||
Identifier Description
|
||
|
||
0 Divide error
|
||
1 Debug exceptions
|
||
2 Nonmaskable interrupt
|
||
3 Breakpoint (one-byte INT 3 instruction)
|
||
4 Overflow (INTO instruction)
|
||
5 Bounds check (BOUND instruction)
|
||
6 Invalid opcode
|
||
7 Coprocessor not available
|
||
8 Double fault
|
||
9 (reserved)
|
||
10 Invalid TSS
|
||
11 Segment not present
|
||
12 Stack exception
|
||
13 General protection
|
||
14 Page fault
|
||
15 (reserved)
|
||
16 Coprecessor error
|
||
17-31 (reserved)
|
||
32-255 Available for external interrupts via INTR pin
|
||
|
||
|
||
9.2 Enabling and Disabling Interrupts
|
||
|
||
The processor services interrupts and exceptions only between the end of
|
||
one instruction and the beginning of the next. When the repeat prefix is
|
||
used to repeat a string instruction, interrupts and exceptions may occur
|
||
between repetitions. Thus, operations on long strings do not delay interrupt
|
||
response.
|
||
|
||
Certain conditions and flag settings cause the processor to inhibit certain
|
||
interrupts and exceptions at instruction boundaries.
|
||
|
||
|
||
9.2.1 NMI Masks Further NMIs
|
||
|
||
While an NMI handler is executing, the processor ignores further interrupt
|
||
signals at the NMI pin until the next IRET instruction is executed.
|
||
|
||
|
||
9.2.2 IF Masks INTR
|
||
|
||
The IF (interrupt-enable flag) controls the acceptance of external
|
||
interrupts signalled via the INTR pin. When IF=0, INTR interrupts are
|
||
inhibited; when IF=1, INTR interrupts are enabled. As with the other flag
|
||
bits, the processor clears IF in response to a RESET signal. The
|
||
instructions CLI and STI alter the setting of IF.
|
||
|
||
CLI (Clear Interrupt-Enable Flag) and STI (Set Interrupt-Enable Flag)
|
||
explicitly alter IF (bit 9 in the flag register). These instructions may be
|
||
executed only if CPL ó IOPL. A protection exception occurs if they are
|
||
executed when CPL > IOPL.
|
||
|
||
The IF is also affected implicitly by the following operations:
|
||
|
||
þ The instruction PUSHF stores all flags, including IF, in the stack
|
||
where they can be examined.
|
||
|
||
þ Task switches and the instructions POPF and IRET load the flags
|
||
register; therefore, they can be used to modify IF.
|
||
|
||
þ Interrupts through interrupt gates automatically reset IF, disabling
|
||
interrupts. (Interrupt gates are explained later in this chapter.)
|
||
|
||
|
||
9.2.3 RF Masks Debug Faults
|
||
|
||
The RF bit in EFLAGS controls the recognition of debug faults. This permits
|
||
debug faults to be raised for a given instruction at most once, no matter
|
||
how many times the instruction is restarted. (Refer to Chapter 12 for more
|
||
information on debugging.)
|
||
|
||
|
||
9.2.4 MOV or POP to SS Masks Some Interrupts and Exceptions
|
||
|
||
Software that needs to change stack segments often uses a pair of
|
||
instructions; for example:
|
||
|
||
MOV SS, AX
|
||
MOV ESP, StackTop
|
||
|
||
If an interrupt or exception is processed after SS has been changed but
|
||
before ESP has received the corresponding change, the two parts of the stack
|
||
pointer SS:ESP are inconsistent for the duration of the interrupt handler or
|
||
exception handler.
|
||
|
||
To prevent this situation, the 80386, after both a MOV to SS and a POP to
|
||
SS instruction, inhibits NMI, INTR, debug exceptions, and single-step traps
|
||
at the instruction boundary following the instruction that changes SS. Some
|
||
exceptions may still occur; namely, page fault and general protection fault.
|
||
Always use the 80386 LSS instruction, and the problem will not occur.
|
||
|
||
|
||
9.3 Priority Among Simultaneous Interrupts and Exceptions
|
||
|
||
If more than one interrupt or exception is pending at an instruction
|
||
boundary, the processor services one of them at a time. The priority among
|
||
classes of interrupt and exception sources is shown in Table 9-2. The
|
||
processor first services a pending interrupt or exception from the class
|
||
that has the highest priority, transferring control to the first
|
||
instruction of the interrupt handler. Lower priority exceptions are
|
||
discarded; lower priority interrupts are held pending. Discarded exceptions
|
||
will be rediscovered when the interrupt handler returns control to the point
|
||
of interruption.
|
||
|
||
|
||
9.4 Interrupt Descriptor Table
|
||
|
||
The interrupt descriptor table (IDT) associates each interrupt or exception
|
||
identifier with a descriptor for the instructions that service the
|
||
associated event. Like the GDT and LDTs, the IDT is an array of 8-byte
|
||
descriptors. Unlike the GDT and LDTs, the first entry of the IDT may contain
|
||
a descriptor. To form an index into the IDT, the processor multiplies the
|
||
interrupt or exception identifier by eight. Because there are only 256
|
||
identifiers, the IDT need not contain more than 256 descriptors. It can
|
||
contain fewer than 256 entries; entries are required only for interrupt
|
||
identifiers that are actually used.
|
||
|
||
The IDT may reside anywhere in physical memory. As Figure 9-1 shows, the
|
||
processor locates the IDT by means of the IDT register (IDTR). The
|
||
instructions LIDT and SIDT operate on the IDTR. Both instructions have one
|
||
explicit operand: the address in memory of a 6-byte area. Figure 9-2 shows
|
||
the format of this area.
|
||
|
||
LIDT (Load IDT register) loads the IDT register with the linear base
|
||
address and limit values contained in the memory operand. This instruction
|
||
can be executed only when the CPL is zero. It is normally used by the
|
||
initialization logic of an operating system when creating an IDT. An
|
||
operating system may also use it to change from one IDT to another.
|
||
|
||
SIDT (Store IDT register) copies the base and limit value stored in IDTR
|
||
to a memory location. This instruction can be executed at any privilege
|
||
level.
|
||
|
||
|
||
Table 9-2. Priority Among Simultaneous Interrupts and Exceptions
|
||
|
||
Priority Class of Interrupt or Exception
|
||
|
||
HIGHEST Faults except debug faults
|
||
Trap instructions INTO, INT n, INT 3
|
||
Debug traps for this instruction
|
||
Debug faults for next instruction
|
||
NMI interrupt
|
||
LOWEST INTR interrupt
|
||
|
||
|
||
Figure 9-1. IDT Register and Table
|
||
|
||
INTERRUPT DESCRIPTOR TABLE
|
||
ÉÍÍÍÍÍÍÑÍÍÍÍÍÑÍÍÍÍÍÑÍÍÍÍÍÍ»
|
||
ÚÄÄÄĺ ³ ³ ³ º
|
||
³ ÇÄ GATE FOR INTERRUPT #N Ķ
|
||
³ º ³ ³ ³ º
|
||
³ ÈÍÍÍÍÍÍÏÍÍÍÍÍÏÍÍÍÍÍÏÍÍÍÍÍͼ
|
||
³
|
||
³
|
||
³
|
||
³ ÉÍÍÍÍÍÍÑÍÍÍÍÍÑÍÍÍÍÍÑÍÍÍÍÍÍ»
|
||
³ º ³ ³ ³ º
|
||
³ ÇÄ GATE FOR INTERRUPT #2 Ķ
|
||
³ º ³ ³ ³ º
|
||
³ ÌÍÍÍÍÍÍÑÍÍÍÍÍÑÍÍÍÍÍÑÍÍÍÍÍ͹
|
||
IDT REGISTER ³ º ³ ³ ³ º
|
||
³ ÇÄ GATE FOR INTERRUPT #1 Ķ
|
||
15 0 ³ º ³ ³ ³ º
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» ³ ÌÍÍÍÍÍÍÑÍÍÍÍÍÑÍÍÍÍÍÑÍÍÍÍÍ͹
|
||
º IDT LIMIT ÇÄÄÄÄÙ º ³ ³ ³ º
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ ÇÄ GATE FOR INTERRUPT #0 Ķ
|
||
º IDT BASE ÇÄÄÄÄÄÄÄÄĺ ³ ³ ³ º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ ÈÍÍÍÍÍÍÏÍÍÍÍÍÏÍÍÍÍÍÏÍÍÍÍÍͼ
|
||
31 0
|
||
|
||
|
||
Figure 9-2. Pseudo-Descriptor Format for LIDT and SIDT
|
||
|
||
31 23 15 7 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º BASE º2
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
º LIMIT º0
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
|
||
9.5 IDT Descriptors
|
||
|
||
The IDT may contain any of three kinds of descriptor:
|
||
|
||
þ Task gates
|
||
þ Interrupt gates
|
||
þ Trap gates
|
||
|
||
Figure 9-3 illustrates the format of task gates and 80386 interrupt gates
|
||
and trap gates. (The task gate in an IDT is the same as the task gate
|
||
already discussed in Chapter 7.)
|
||
|
||
|
||
Figure 9-3. 80306 IDT Gate Descriptors
|
||
|
||
80386 TASK GATE
|
||
31 23 15 7 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÑÍÍÍÑÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º±±±±±±±±±±±±±(NOT USED)±±±±±±±±±±±±³ P ³DPL³0 0 1 0 1³±±±(NOT USED)±±±±º4
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÁÄÄÄÁÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º SELECTOR ³±±±±±±±±±±±±±(NOT USED)±±±±±±±±±±±±º0
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
80386 INTERRUPT GATE
|
||
31 23 15 7 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÑÍÍÍÑÍÍÍÍÍÍÍÍÍØÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º OFFSET 31..16 ³ P ³DPL³0 1 1 1 0³0 0 0³(NOT USED) º4
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÁÄÄÄÁÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄĶ
|
||
º SELECTOR ³ OFFSET 15..0 º0
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
80386 TRAP GATE
|
||
31 23 15 7 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÑÍÍÍÑÍÍÍÍÍÍÍÍÍØÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º OFFSET 31..16 ³ P ³DPL³0 1 1 1 1³0 0 0³(NOT USED) º4
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÁÄÄÄÁÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄĶ
|
||
º SELECTOR ³ OFFSET 15..0 º0
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
|
||
9.6 Interrupt Tasks and Interrupt Procedures
|
||
|
||
Just as a CALL instruction can call either a procedure or a task, so an
|
||
interrupt or exception can "call" an interrupt handler that is either a
|
||
procedure or a task. When responding to an interrupt or exception, the
|
||
processor uses the interrupt or exception identifier to index a descriptor
|
||
in the IDT. If the processor indexes to an interrupt gate or trap gate, it
|
||
invokes the handler in a manner similar to a CALL to a call gate. If the
|
||
processor finds a task gate, it causes a task switch in a manner similar to
|
||
a CALL to a task gate.
|
||
|
||
|
||
9.6.1 Interrupt Procedures
|
||
|
||
An interrupt gate or trap gate points indirectly to a procedure which will
|
||
execute in the context of the currently executing task as illustrated by
|
||
Figure 9-4. The selector of the gate points to an executable-segment
|
||
descriptor in either the GDT or the current LDT. The offset field of the
|
||
gate points to the beginning of the interrupt or exception handling
|
||
procedure.
|
||
|
||
The 80386 invokes an interrupt or exception handling procedure in much the
|
||
same manner as it CALLs a procedure; the differences are explained in the
|
||
following sections.
|
||
|
||
|
||
Figure 9-4. Interrupt Vectoring for Procedures
|
||
|
||
IDT EXECUTABLE SEGMENT
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º º OFFSETº º
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĺ ENTRY POINT º
|
||
º º ³ LDT OR GDT º º
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ ³ ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» º º
|
||
º º ³ º º º º
|
||
INTERRUPT ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ ³ ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ º º
|
||
IDÄÄÄÄĺ TRAP GATE OR ÇÄÄÙ º º º º
|
||
ºINTERRUPT GATE ÇÄÄ¿ ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ º º
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ ³ º º º º
|
||
º º ³ ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ º º
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ ÀÄĺ SEGMENT ÇÄ¿ º º
|
||
º º º DESCRIPTOR º ³ º º
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ ³ º º
|
||
º º º º ³ º º
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ ³ º º
|
||
º º º º ³BASEº º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ ÀÄÄÄÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
º º
|
||
º º
|
||
º º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
|
||
9.6.1.1 Stack of Interrupt Procedure
|
||
|
||
Just as with a control transfer due to a CALL instruction, a control
|
||
transfer to an interrupt or exception handling procedure uses the stack to
|
||
store the information needed for returning to the original procedure. As
|
||
Figure 9-5 shows, an interrupt pushes the EFLAGS register onto the stack
|
||
before the pointer to the interrupted instruction.
|
||
|
||
Certain types of exceptions also cause an error code to be pushed on the
|
||
stack. An exception handler can use the error code to help diagnose the
|
||
exception.
|
||
|
||
|
||
9.6.1.2 Returning from an Interrupt Procedure
|
||
|
||
An interrupt procedure also differs from a normal procedure in the method
|
||
of leaving the procedure. The IRET instruction is used to exit from an
|
||
interrupt procedure. IRET is similar to RET except that IRET increments EIP
|
||
by an extra four bytes (because of the flags on the stack) and moves the
|
||
saved flags into the EFLAGS register. The IOPL field of EFLAGS is changed
|
||
only if the CPL is zero. The IF flag is changed only if CPL ó IOPL.
|
||
|
||
|
||
Figure 9-5. Stack Layout after Exception of Interrupt
|
||
|
||
WITHOUT PRIVILEGE TRANSITION
|
||
|
||
D O 31 0 31 0
|
||
I F ÌÍÍÍÍÍÍÍËÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍËÍÍÍÍÍÍ͹
|
||
R º±±±±±±±º±±±±±±±º OLD º±±±±±±±º±±±±±±±º OLD
|
||
E E ÌÍÍÍÍÍÍÍÎÍÍÍÍÍÍ͹ SS:ESP ÌÍÍÍÍÍÍÍÎÍÍÍÍÍÍ͹ SS:ESP
|
||
C X º±±±±±±±º±±±±±±±º ³ º±±±±±±±º±±±±±±±º ³
|
||
T P ÌÍÍÍÍÍÍÍÊÍÍÍÍÍÍ͹ÄÄÄÄÙ ÌÍÍÍÍÍÍÍÊÍÍÍÍÍÍ͹ÄÄÄÄÙ
|
||
I A º OLD EFLAGS º º OLD EFLAGS º
|
||
O N ÌÍÍÍÍÍÍÍËÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍËÍÍÍÍÍÍ͹
|
||
N S º±±±±±±±ºOLD CS º NEW º±±±±±±±ºOLD CS º
|
||
I ÌÍÍÍÍÍÍÍÊÍÍÍÍÍÍ͹ SS:ESP ÌÍÍÍÍÍÍÍÊÍÍÍÍÍÍ͹
|
||
³ O º OLD EIP º ³ º OLD EIP º NEW
|
||
³ N ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ÄÄÄÄÙ ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ SS:ESP
|
||
³ º º º ERROR CODE º ³
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ÄÄÄÄÙ
|
||
º º
|
||
|
||
WITHOUT ERROR CODE WITH ERROR CODE
|
||
|
||
WITH PRIVILEGE TRANSITION
|
||
|
||
D O 31 0 31 0
|
||
I F ÉÍÍÍÍÍÍÍËÍÍÍÍÍÍÍ»ÄÄÄÄ¿ ÉÍÍÍÍÍÍÍËÍÍÍÍÍÍÍ»ÄÄÄÄ¿
|
||
R º±±±±±±±ºOLD SS º ³ º±±±±±±±ºOLD SS º ³
|
||
E E ÌÍÍÍÍÍÍÍÊÍÍÍÍÍÍ͹ SS:ESP ÌÍÍÍÍÍÍÍÊÍÍÍÍÍÍ͹ SS:ESP
|
||
C X º OLD ESP º FROM TSS º OLD ESP º FROM TSS
|
||
T P ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
I A º OLD EFLAGS º º OLD EFLAGS º
|
||
O N ÌÍÍÍÍÍÍÍËÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍËÍÍÍÍÍÍ͹
|
||
N S º±±±±±±±ºOLD CS º NEW º±±±±±±±ºOLD CS º
|
||
I ÌÍÍÍÍÍÍÍÊÍÍÍÍÍÍ͹ SS:EIP ÌÍÍÍÍÍÍÍÊÍÍÍÍÍÍ͹
|
||
³ O º OLD EIP º ³ º OLD EIP º NEW
|
||
³ N ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ÄÄÄÄÙ ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ SS:ESP
|
||
³ º º º ERROR CODE º ³
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ÄÄÄÄÙ
|
||
º º
|
||
|
||
WITHOUT ERROR CODE WITH ERROR CODE
|
||
|
||
|
||
9.6.1.3 Flags Usage by Interrupt Procedure
|
||
|
||
Interrupts that vector through either interrupt gates or trap gates cause
|
||
TF (the trap flag) to be reset after the current value of TF is saved on the
|
||
stack as part of EFLAGS. By this action the processor prevents debugging
|
||
activity that uses single-stepping from affecting interrupt response. A
|
||
subsequent IRET instruction restores TF to the value in the EFLAGS image on
|
||
the stack.
|
||
|
||
The difference between an interrupt gate and a trap gate is in the effect
|
||
on IF (the interrupt-enable flag). An interrupt that vectors through an
|
||
interrupt gate resets IF, thereby preventing other interrupts from
|
||
interfering with the current interrupt handler. A subsequent IRET
|
||
instruction restores IF to the value in the EFLAGS image on the stack. An
|
||
interrupt through a trap gate does not change IF.
|
||
|
||
|
||
9.6.1.4 Protection in Interrupt Procedures
|
||
|
||
The privilege rule that governs interrupt procedures is similar to that for
|
||
procedure calls: the CPU does not permit an interrupt to transfer control to
|
||
a procedure in a segment of lesser privilege (numerically greater privilege
|
||
level) than the current privilege level. An attempt to violate this rule
|
||
results in a general protection exception.
|
||
|
||
Because occurrence of interrupts is not generally predictable, this
|
||
privilege rule effectively imposes restrictions on the privilege levels at
|
||
which interrupt and exception handling procedures can execute. Either of the
|
||
following strategies can be employed to ensure that the privilege rule is
|
||
never violated.
|
||
|
||
þ Place the handler in a conforming segment. This strategy suits the
|
||
handlers for certain exceptions (divide error, for example). Such a
|
||
handler must use only the data available to it from the stack. If it
|
||
needed data from a data segment, the data segment would have to have
|
||
privilege level three, thereby making it unprotected.
|
||
|
||
þ Place the handler procedure in a privilege level zero segment.
|
||
|
||
|
||
9.6.2 Interrupt Tasks
|
||
|
||
A task gate in the IDT points indirectly to a task, as Figure 9-6
|
||
illustrates. The selector of the gate points to a TSS descriptor in the GDT.
|
||
|
||
When an interrupt or exception vectors to a task gate in the IDT, a task
|
||
switch results. Handling an interrupt with a separate task offers two
|
||
advantages:
|
||
|
||
þ The entire context is saved automatically.
|
||
|
||
þ The interrupt handler can be isolated from other tasks by giving it a
|
||
separate address space, either via its LDT or via its page directory.
|
||
|
||
The actions that the processor takes to perform a task switch are discussed
|
||
in Chapter 7. The interrupt task returns to the interrupted task by
|
||
executing an IRET instruction.
|
||
|
||
If the task switch is caused by an exception that has an error code, the
|
||
processor automatically pushes the error code onto the stack that
|
||
corresponds to the privilege level of the first instruction to be executed
|
||
in the interrupt task.
|
||
|
||
When interrupt tasks are used in an operating system for the 80386, there
|
||
are actually two schedulers: the software scheduler (part of the operating
|
||
system) and the hardware scheduler (part of the processor's interrupt
|
||
mechanism). The design of the software scheduler should account for the fact
|
||
that the hardware scheduler may dispatch an interrupt task whenever
|
||
interrupts are enabled.
|
||
|
||
|
||
Figure 9-6. Interrupt Vectoring for Tasks
|
||
|
||
IDT GDT
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º º º º TSS
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º º º º º º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ º º
|
||
º º º º º º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ º º
|
||
ÚÄĺ TASK GATE ÇÄÄÄ¿ º º º º
|
||
³ ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ ³ ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ º º
|
||
³ º º ÀÄÄĺ TSS DESCRIPTOR ÇÄÄÄ¿ º º
|
||
³ ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ ³ º º
|
||
³ º º º º ³ º º
|
||
³ ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ ÀÄÄÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
³ º º º º
|
||
³ ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
³ º º º º
|
||
³ ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
³
|
||
ÀÄINTERRUPT ID
|
||
|
||
|
||
9.7 Error Code
|
||
|
||
With exceptions that relate to a specific segment, the processor pushes an
|
||
error code onto the stack of the exception handler (whether procedure or
|
||
task). The error code has the format shown in Figure 9-7. The format of the
|
||
error code resembles that of a selector; however, instead of an RPL field,
|
||
the error code contains two one-bit items:
|
||
|
||
1. The processor sets the EXT bit if an event external to the program
|
||
caused the exception.
|
||
|
||
2. The processor sets the I-bit (IDT-bit) if the index portion of the
|
||
error code refers to a gate descriptor in the IDT.
|
||
|
||
If the I-bit is not set, the TI bit indicates whether the error code refers
|
||
to the GDT (value 0) or to the LDT (value 1). The remaining 14 bits are the
|
||
upper 14 bits of the segment selector involved. In some cases the error code
|
||
on the stack is null, i.e., all bits in the low-order word are zero.
|
||
|
||
|
||
Figure 9-7. Error Code Format
|
||
|
||
31 15 2 1 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÑÍÑÍÑÍ»
|
||
º±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±³ ³T³ ³Eº
|
||
º±±±±±±±±±±±UNDEFINED±±±±±±±±±±±±³ SELECTOR INDEX ³ ³I³ º
|
||
º±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±³ ³I³ ³Xº
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÏÍÏÍÏͼ
|
||
|
||
|
||
9.8 Exception Conditions
|
||
|
||
The following sections describe each of the possible exception conditions
|
||
in detail. Each description classifies the exception as a fault, trap, or
|
||
abort. This classification provides information needed by systems
|
||
programmers for restarting the procedure in which the exception occurred:
|
||
|
||
Faults The CS and EIP values saved when a fault is reported point to the
|
||
instruction causing the fault.
|
||
|
||
Traps The CS and EIP values stored when the trap is reported point to the
|
||
instruction dynamically after the instruction causing the trap. If
|
||
a trap is detected during an instruction that alters program flow,
|
||
the reported values of CS and EIP reflect the alteration of program
|
||
flow. For example, if a trap is detected in a JMP instruction, the
|
||
CS and EIP values pushed onto the stack point to the target of the
|
||
JMP, not to the instruction after the JMP.
|
||
|
||
Aborts An abort is an exception that permits neither precise location of
|
||
the instruction causing the exception nor restart of the program
|
||
that caused the exception. Aborts are used to report severe errors,
|
||
such as hardware errors and inconsistent or illegal values in
|
||
system tables.
|
||
|
||
|
||
9.8.1 Interrupt 0 ÄÄ Divide Error
|
||
|
||
The divide-error fault occurs during a DIV or an IDIV instruction when the
|
||
divisor is zero.
|
||
|
||
|
||
9.8.2 Interrupt 1 ÄÄ Debug Exceptions
|
||
|
||
The processor triggers this interrupt for any of a number of conditions;
|
||
whether the exception is a fault or a trap depends on the condition:
|
||
|
||
þ Instruction address breakpoint fault.
|
||
þ Data address breakpoint trap.
|
||
þ General detect fault.
|
||
þ Single-step trap.
|
||
þ Task-switch breakpoint trap.
|
||
|
||
The processor does not push an error code for this exception. An exception
|
||
handler can examine the debug registers to determine which condition caused
|
||
the exception. Refer to Chapter 12 for more detailed information about
|
||
debugging and the debug registers.
|
||
|
||
|
||
9.8.3 Interrupt 3 ÄÄ Breakpoint
|
||
|
||
The INT 3 instruction causes this trap. The INT 3 instruction is one byte
|
||
long, which makes it easy to replace an opcode in an executable segment with
|
||
the breakpoint opcode. The operating system or a debugging subsystem can use
|
||
a data-segment alias for an executable segment to place an INT 3 anywhere it
|
||
is convenient to arrest normal execution so that some sort of special
|
||
processing can be performed. Debuggers typically use breakpoints as a way of
|
||
displaying registers, variables, etc., at crucial points in a task.
|
||
|
||
The saved CS:EIP value points to the byte following the breakpoint. If a
|
||
debugger replaces a planted breakpoint with a valid opcode, it must subtract
|
||
one from the saved EIP value before returning. Refer also to Chapter 12 for
|
||
more information on debugging.
|
||
|
||
|
||
9.8.4 Interrupt 4 ÄÄ Overflow
|
||
|
||
This trap occurs when the processor encounters an INTO instruction and the
|
||
OF (overflow) flag is set. Since signed arithmetic and unsigned arithmetic
|
||
both use the same arithmetic instructions, the processor cannot determine
|
||
which is intended and therefore does not cause overflow exceptions
|
||
automatically. Instead it merely sets OF when the results, if interpreted as
|
||
signed numbers, would be out of range. When doing arithmetic on signed
|
||
operands, careful programmers and compilers either test OF directly or use
|
||
the INTO instruction.
|
||
|
||
|
||
9.8.5 Interrupt 5 ÄÄ Bounds Check
|
||
|
||
This fault occurs when the processor, while executing a BOUND instruction,
|
||
finds that the operand exceeds the specified limits. A program can use the
|
||
BOUND instruction to check a signed array index against signed limits
|
||
defined in a block of memory.
|
||
|
||
|
||
9.8.6 Interrupt 6 ÄÄ Invalid Opcode
|
||
|
||
This fault occurs when an invalid opcode is detected by the execution unit.
|
||
(The exception is not detected until an attempt is made to execute the
|
||
invalid opcode; i.e., prefetching an invalid opcode does not cause this
|
||
exception.) No error code is pushed on the stack. The exception can be
|
||
handled within the same task.
|
||
|
||
This exception also occurs when the type of operand is invalid for the
|
||
given opcode. Examples include an intersegment JMP referencing a register
|
||
operand, or an LES instruction with a register source operand.
|
||
|
||
|
||
9.8.7 Interrupt 7 ÄÄ Coprocessor Not Available
|
||
|
||
This exception occurs in either of two conditions:
|
||
|
||
þ The processor encounters an ESC (escape) instruction, and the EM
|
||
(emulate) bit ofCR0 (control register zero) is set.
|
||
|
||
þ The processor encounters either the WAIT instruction or an ESC
|
||
instruction, and both the MP (monitor coprocessor) and TS (task
|
||
switched) bits of CR0 are set.
|
||
|
||
Refer to Chapter 11 for information about the coprocessor interface.
|
||
|
||
|
||
9.8.8 Interrupt 8 ÄÄ Double Fault
|
||
|
||
Normally, when the processor detects an exception while trying to invoke
|
||
the handler for a prior exception, the two exceptions can be handled
|
||
serially. If, however, the processor cannot handle them serially, it signals
|
||
the double-fault exception instead. To determine when two faults are to be
|
||
signalled as a double fault, the 80386 divides the exceptions into three
|
||
classes: benign exceptions, contributory exceptions, and page faults. Table
|
||
9-3 shows this classification.
|
||
|
||
Table 9-4 shows which combinations of exceptions cause a double fault and
|
||
which do not.
|
||
|
||
The processor always pushes an error code onto the stack of the
|
||
double-fault handler; however, the error code is always zero. The faulting
|
||
instruction may not be restarted. If any other exception occurs while
|
||
attempting to invoke the double-fault handler, the processor shuts down.
|
||
|
||
|
||
Table 9-3. Double-Fault Detection Classes
|
||
|
||
Class ID Description
|
||
|
||
1 Debug exceptions
|
||
2 NMI
|
||
3 Breakpoint
|
||
Benign 4 Overflow
|
||
Exceptions 5 Bounds check
|
||
6 Invalid opcode
|
||
7 Coprocessor not available
|
||
16 Coprocessor error
|
||
|
||
0 Divide error
|
||
9 Coprocessor Segment Overrun
|
||
Contributory 10 Invalid TSS
|
||
Exceptions 11 Segment not present
|
||
12 Stack exception
|
||
13 General protection
|
||
|
||
Page Faults 14 Page fault
|
||
|
||
|
||
Table 9-4. Double-Fault Definition
|
||
|
||
SECOND EXCEPTION
|
||
|
||
Benign Contributory Page
|
||
Exception Exception Fault
|
||
|
||
|
||
Benign OK OK OK
|
||
Exception
|
||
|
||
FIRST Contributory OK DOUBLE OK
|
||
EXCEPTION Exception
|
||
|
||
Page
|
||
Fault OK DOUBLE DOUBLE
|
||
|
||
|
||
9.8.9 Interrupt 9 ÄÄ Coprocessor Segment Overrun
|
||
|
||
This exception is raised in protected mode if the 80386 detects a page or
|
||
segment violation while transferring the middle portion of a coprocessor
|
||
operand to the NPX. This exception is avoidable. Refer to Chapter 11 for
|
||
more information about the coprocessor interface.
|
||
|
||
|
||
9.8.10 Interrupt 10 ÄÄ Invalid TSS
|
||
|
||
Interrupt 10 occurs if during a task switch the new TSS is invalid. A TSS
|
||
is considered invalid in the cases shown in Table 9-5. An error code is
|
||
pushed onto the stack to help identify the cause of the fault. The EXT bit
|
||
indicates whether the exception was caused by a condition outside the
|
||
control of the program; e.g., an external interrupt via a task gate
|
||
triggered a switch to an invalid TSS.
|
||
|
||
This fault can occur either in the context of the original task or in the
|
||
context of the new task. Until the processor has completely verified the
|
||
presence of the new TSS, the exception occurs in the context of the original
|
||
task. Once the existence of the new TSS is verified, the task switch is
|
||
considered complete; i.e., TR is updated and, if the switch is due to a
|
||
CALL or interrupt, the backlink of the new TSS is set to the old TSS. Any
|
||
errors discovered by the processor after this point are handled in the
|
||
context of the new task.
|
||
|
||
To insure a proper TSS to process it, the handler for exception 10 must be
|
||
a task invoked via a task gate.
|
||
|
||
|
||
Table 9-5. Conditions That Invalidate the TSS
|
||
|
||
Error Code Condition
|
||
|
||
TSS id + EXT The limit in the TSS descriptor is less than 103
|
||
LTD id + EXT Invalid LDT selector or LDT not present
|
||
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 < > CPL
|
||
CS id + EXT Code segment selector is outside table limit
|
||
CS id + EXT Code segment selector does not refer to code
|
||
segment
|
||
CS id + EXT DPL of non-conforming code segment < > new CPL
|
||
CS id + EXT DPL of conforming code segment > new CPL
|
||
DS/ES/FS/GS id + EXT DS, ES, FS, or GS segment selector is outside
|
||
table limits
|
||
DS/ES/FS/GS id + EXT DS, ES, FS, or GS is not readable segment
|
||
|
||
|
||
9.8.11 Interrupt 11 ÄÄ Segment Not Present
|
||
|
||
Exception 11 occurs when the processor detects that the present bit of a
|
||
descriptor is zero. The processor can trigger this fault in any of these
|
||
cases:
|
||
|
||
þ While attempting to load the CS, DS, ES, FS, or GS registers; loading
|
||
the SS register, however, causes a stack fault.
|
||
|
||
þ While attempting loading the LDT register with an LLDT instruction;
|
||
loading the LDT register during a task switch operation, however,
|
||
causes the "invalid TSS" exception.
|
||
|
||
þ While attempting to use a gate descriptor that is marked not-present.
|
||
|
||
This fault is restartable. If the exception handler makes the segment
|
||
present and returns, the interrupted program will resume execution.
|
||
|
||
If a not-present exception occurs during a task switch, not all the steps
|
||
of the task switch are complete. During a task switch, the processor first
|
||
loads all the segment registers, then checks their contents for validity. If
|
||
a not-present exception is discovered, the remaining segment registers have
|
||
not been checked and therefore may not be usable for referencing memory. The
|
||
not-present handler should not rely on being able to use the values found
|
||
in CS, SS, DS, ES, FS, and GS without causing another exception. The
|
||
exception handler should check all segment registers before trying to resume
|
||
the new task; otherwise, general protection faults may result later under
|
||
conditions that make diagnosis more difficult. There are three ways to
|
||
handle this case:
|
||
|
||
1. Handle the not-present fault with a task. The task switch back to the
|
||
interrupted task will cause the processor to check the registers as it
|
||
loads them from the TSS.
|
||
|
||
2. PUSH and POP all segment registers. Each POP causes the processor to
|
||
check the new contents of the segment register.
|
||
|
||
3. Scrutinize the contents of each segment-register image in the TSS,
|
||
simulating the test that the processor makes when it loads a segment
|
||
register.
|
||
|
||
This exception pushes an error code onto the stack. The EXT bit of the
|
||
error code is set if an event external to the program caused an interrupt
|
||
that subsequently referenced a not-present segment. The I-bit is set if the
|
||
error code refers to an IDT entry, e.g., an INT instruction referencing a
|
||
not-present gate.
|
||
|
||
An operating system typically uses the "segment not present" exception to
|
||
implement virtual memory at the segment level. A not-present indication in a
|
||
gate descriptor, however, usually does not indicate that a segment is not
|
||
present (because gates do not necessarily correspond to segments).
|
||
Not-present gates may be used by an operating system to trigger exceptions
|
||
of special significance to the operating system.
|
||
|
||
|
||
9.8.12 Interrupt 12 ÄÄ Stack Exception
|
||
|
||
A stack fault occurs in either of two general conditions:
|
||
|
||
þ As a result of a limit violation in any operation that refers to the
|
||
SS register. This includes stack-oriented instructions such as POP,
|
||
PUSH, ENTER, and LEAVE, as well as other memory references that
|
||
implicitly use SS (for example, MOV AX, [BP+6]). ENTER causes this
|
||
exception when the stack is too small for the indicated local-variable
|
||
space.
|
||
|
||
þ When attempting to load the SS register with a descriptor that is
|
||
marked not-present but is otherwise valid. This can occur in a task
|
||
switch, an interlevel CALL, an interlevel return, an LSS instruction,
|
||
or a MOV or POP instruction to SS.
|
||
|
||
When the processor detects a stack exception, it pushes an error code onto
|
||
the stack of the exception handler. If the exception is due to a not-present
|
||
stack segment or to overflow of the new stack during an interlevel CALL, the
|
||
error code contains a selector to the segment in question (the exception
|
||
handler can test the present bit in the descriptor to determine which
|
||
exception occurred); otherwise the error code is zero.
|
||
|
||
An instruction that causes this fault is restartable in all cases. The
|
||
return pointer pushed onto the exception handler's stack points to the
|
||
instruction that needs to be restarted. This instruction is usually the one
|
||
that caused the exception; however, in the case of a stack exception due to
|
||
loading of a not-present stack-segment descriptor during a task switch, the
|
||
indicated instruction is the first instruction of the new task.
|
||
|
||
When a stack fault occurs during a task switch, the segment registers may
|
||
not be usable for referencing memory. During a task switch, the selector
|
||
values are loaded before the descriptors are checked. If a stack fault is
|
||
discovered, the remaining segment registers have not been checked and
|
||
therefore may not be usable for referencing memory. The stack fault handler
|
||
should not rely on being able to use the values found in CS, SS, DS, ES,
|
||
FS, and GS without causing another exception. The exception handler should
|
||
check all segment registers before trying to resume the new task; otherwise,
|
||
general protection faults may result later under conditions that make
|
||
diagnosis more difficult.
|
||
|
||
|
||
9.8.13 Interrupt 13 ÄÄ General Protection Exception
|
||
|
||
All protection violations that do not cause another exception cause a
|
||
general protection exception. This includes (but is not limited to):
|
||
|
||
1. Exceeding segment limit when using CS, DS, ES, FS, or GS
|
||
|
||
2. Exceeding segment limit when referencing a descriptor table
|
||
|
||
3. Transferring control to a segment that is not executable
|
||
|
||
4. Writing into a read-only data segment or into a code segment
|
||
|
||
5. Reading from an execute-only segment
|
||
|
||
6. Loading the SS register with a read-only descriptor (unless the
|
||
selector comes from the TSS during a task switch, in which case a TSS
|
||
exception occurs
|
||
|
||
7. Loading SS, DS, ES, FS, or GS with the descriptor of a system segment
|
||
|
||
8. Loading DS, ES, FS, or GS with the descriptor of an executable
|
||
segment that is not also readable
|
||
|
||
9. Loading SS with the descriptor of an executable segment
|
||
|
||
10. Accessing memory via DS, ES, FS, or GS when the segment register
|
||
contains a null selector
|
||
|
||
11. Switching to a busy task
|
||
|
||
12. Violating privilege rules
|
||
|
||
13. Loading CR0 with PG=1 and PE=0.
|
||
|
||
14. Interrupt or exception via trap or interrupt gate from V86 mode to
|
||
privilege level other than zero.
|
||
|
||
15. Exceeding the instruction length limit of 15 bytes (this can occur
|
||
only if redundant prefixes are placed before an instruction)
|
||
|
||
The general protection exception is a fault. In response to a general
|
||
protection exception, the processor pushes an error code onto the exception
|
||
handler's stack. If loading a descriptor causes the exception, the error
|
||
code contains a selector to the descriptor; otherwise, the error code is
|
||
null. The source of the selector in an error code may be any of the
|
||
following:
|
||
|
||
1. An operand of the instruction.
|
||
2. A selector from a gate that is the operand of the instruction.
|
||
3. A selector from a TSS involved in a task switch.
|
||
|
||
|
||
9.8.14 Interrupt 14 ÄÄ Page Fault
|
||
|
||
This exception occurs when paging is enabled (PG=1) and the processor
|
||
detects one of the following conditions while translating a linear address
|
||
to a physical address:
|
||
|
||
þ The page-directory or page-table entry needed for the address
|
||
translation has zero in its present bit.
|
||
|
||
þ The current procedure does not have sufficient privilege to access the
|
||
indicated page.
|
||
|
||
The processor makes available to the page fault handler two items of
|
||
information that aid in diagnosing the exception and recovering from it:
|
||
|
||
þ An error code on the stack. The error code for a page fault has a
|
||
format different from that for other exceptions (see Figure 9-8). The
|
||
error code tells the exception handler three things:
|
||
|
||
1. Whether the exception was due to a not present page or to an access
|
||
rights violation.
|
||
|
||
2. Whether the processor was executing at user or supervisor level at
|
||
the time of the exception.
|
||
|
||
3. Whether the memory access that caused the exception was a read or
|
||
write.
|
||
|
||
þ CR2 (control register two). The processor stores in CR2 the linear
|
||
address used in the access that caused the exception (see Figure 9-9).
|
||
The exception handler can use this address to locate the corresponding
|
||
page directory and page table entries. If another page fault can occur
|
||
during execution of the page fault handler, the handler should push CR2
|
||
onto the stack.
|
||
|
||
|
||
Figure 9-8. Page-Fault Error Code Format
|
||
|
||
ÉÍÍÍÍÍÑÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
ºField³Value³ Description º
|
||
ÇÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º U/S ³ 0 ³ The access causing the fault originated when the processor º
|
||
º ³ ³ was executing in supervisor mode. º
|
||
º ³ ³ º
|
||
º ³ 1 ³ The access causing the fault originated when the processor º
|
||
º ³ ³ was executing in user mode. º
|
||
º ³ ³ º
|
||
º W/R ³ 0 ³ The access causing the fault was a read. º
|
||
º ³ ³ º
|
||
º ³ 1 ³ The access causing the fault was a write. º
|
||
º ³ ³ º
|
||
º P ³ 0 ³ The fault was caused by a not-present page. º
|
||
º ³ ³ º
|
||
º ³ 1 ³ The fault was caused by a page-level protection violation. º
|
||
ÈÍÍÍÍÍÏÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
31 15 7 3 2 1 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÑÍÑÍ»
|
||
º±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±³U³W³ º
|
||
º±±±±±±±±±±±±±±±±±±±±±±±±±±UNDEFINED±±±±±±±±±±±±±±±±±±±±±±±³/³/³Pº
|
||
º±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±³S³R³ º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÏÍÏͼ
|
||
|
||
|
||
9.8.14.1 Page Fault During Task Switch
|
||
|
||
The processor may access any of four segments during a task switch:
|
||
|
||
1. Writes the state of the original task in the TSS of that task.
|
||
|
||
2. Reads the GDT to locate the TSS descriptor of the new task.
|
||
|
||
3. Reads the TSS of the new task to check the types of segment
|
||
descriptors from the TSS.
|
||
|
||
4. May read the LDT of the new task in order to verify the segment
|
||
registers stored in the new TSS.
|
||
|
||
A page fault can result from accessing any of these segments. In the latter
|
||
two cases the exception occurs in the context of the new task. The
|
||
instruction pointer refers to the next instruction of the new task, not to
|
||
the instruction that caused the task switch. If the design of the operating
|
||
system permits page faults to occur during task-switches, the page-fault
|
||
handler should be invoked via a task gate.
|
||
|
||
|
||
Figure 9-9. CR2 Format
|
||
|
||
31 23 15 7 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º º
|
||
º PAGE FAULT LINEAR ADDRESS º
|
||
º º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
|
||
9.8.14.2 Page Fault with Inconsistent Stack Pointer
|
||
|
||
Special care should be taken to ensure that a page fault does not cause the
|
||
processor to use an invalid stack pointer (SS:ESP). Software written for
|
||
earlier processors in the 8086 family often uses a pair of instructions to
|
||
change to a new stack; for example:
|
||
|
||
MOV SS, AX
|
||
MOV SP, StackTop
|
||
|
||
With the 80386, because the second instruction accesses memory, it is
|
||
possible to get a page fault after SS has been changed but before SP has
|
||
received the corresponding change. At this point, the two parts of the stack
|
||
pointer SS:SP (or, for 32-bit programs, SS:ESP) are inconsistent.
|
||
|
||
The processor does not use the inconsistent stack pointer if the handling
|
||
of the page fault causes a stack switch to a well defined stack (i.e., the
|
||
handler is a task or a more privileged procedure). However, if the page
|
||
fault handler is invoked by a trap or interrupt gate and the page fault
|
||
occurs at the same privilege level as the page fault handler, the processor
|
||
will attempt to use the stack indicated by the current (invalid) stack
|
||
pointer.
|
||
|
||
In systems that implement paging and that handle page faults within the
|
||
faulting task (with trap or interrupt gates), software that executes at the
|
||
same privilege level as the page fault handler should initialize a new stack
|
||
by using the new LSS instruction rather than an instruction pair shown
|
||
above. When the page fault handler executes at privilege level zero (the
|
||
normal case), the scope of the problem is limited to privilege-level zero
|
||
code, typically the kernel of the operating system.
|
||
|
||
|
||
9.8.15 Interrupt 16 ÄÄ Coprocessor Error
|
||
|
||
The 80386 reports this exception when it detects a signal from the 80287 or
|
||
80387 on the 80386's ERROR# input pin. The 80386 tests this pin only at the
|
||
beginning of certain ESC instructions and when it encounters a WAIT
|
||
instruction while the EM bit of the MSW is zero (no emulation). Refer to
|
||
Chapter 11 for more information on the coprocessor interface.
|
||
|
||
|
||
9.9 Exception Summary
|
||
|
||
|
||
Table 9-6 summarizes the exceptions recognized by the 386.
|
||
|
||
Table 9-6. Exception Summary
|
||
|
||
|
||
Description Interrupt Return Address Exception Function
|
||
That Can Generate
|
||
Number Points to Type the
|
||
Exception
|
||
Faulting
|
||
Instruction
|
||
|
||
Divide error 0 YES FAULT DIV, IDIV
|
||
Debug exceptions 1
|
||
Some debug exceptions are traps and some are faults. The exception
|
||
handler can determine which has occurred by examining DR6. (Refer to
|
||
Chapter 12.)
|
||
Some debug exceptions are traps and some are faults. The exception
|
||
handler can determine which has occurred by examining DR6. (Refer to
|
||
Chapter 12.) Any instruction
|
||
Breakpoint 3 NO TRAP One-byte
|
||
INT 3
|
||
Overflow 4 NO TRAP INTO
|
||
Bounds check 5 YES FAULT BOUND
|
||
Invalid opcode 6 YES FAULT Any
|
||
illegal instruction
|
||
Coprocessor not available 7 YES FAULT ESC, WAIT
|
||
Double fault 8 YES ABORT Any
|
||
instruction that can
|
||
generate
|
||
an exception
|
||
Coprocessor Segment
|
||
Overrun 9 NO ABORT Any
|
||
operand of an ESC
|
||
|
||
instruction that wraps around
|
||
the end of
|
||
a segment.
|
||
Invalid TSS 10 YES FAULT
|
||
An invalid-TSS fault is not restartable if it occurs during the
|
||
processing of an external interrupt. JMP, CALL, IRET, any interrupt
|
||
Segment not present 11 YES FAULT Any
|
||
segment-register modifier
|
||
Stack exception 12 YES FAULT Any memory
|
||
reference thru SS
|
||
General Protection 13 YES FAULT/ABORT
|
||
All GP faults are restartable. If the fault occurs while attempting to
|
||
vector to the handler for an external interrupt, the interrupted program is
|
||
restartable, but the interrupt may be lost. Any memory reference or code
|
||
fetch
|
||
Page fault 14 YES FAULT Any memory
|
||
reference or code
|
||
fetch
|
||
Coprocessor error 16 YES FAULT
|
||
Coprocessor errors are reported as a fault on the first ESC or WAIT
|
||
instruction executed after the ESC instruction that caused the error.
|
||
ESC, WAIT
|
||
Two-byte SW Interrupt 0-255 NO TRAP INT n
|
||
|
||
|
||
9.10 Error Code Summary
|
||
|
||
Table 9-7 summarizes the error information that is available with each
|
||
exception.
|
||
|
||
|
||
Table 9-7. Error-Code Summary
|
||
|
||
Description Interrupt Error Code
|
||
Number
|
||
|
||
Divide error 0 No
|
||
Debug exceptions 1 No
|
||
Breakpoint 3 No
|
||
Overflow 4 No
|
||
Bounds check 5 No
|
||
Invalid opcode 6 No
|
||
Coprocessor not available 7 No
|
||
System error 8 Yes (always 0)
|
||
Coprocessor Segment Overrun 9 No
|
||
Invalid TSS 10 Yes
|
||
Segment not present 11 Yes
|
||
Stack exception 12 Yes
|
||
General protection fault 13 Yes
|
||
Page fault 14 Yes
|
||
Coprocessor error 16 No
|
||
Two-byte SW interrupt 0-255 No
|
||
|
||
|
||
Chapter 10 Initialization
|
||
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
After a signal on the RESET pin, certain registers of the 80386 are set to
|
||
predefined values. These values are adequate to enable execution of a
|
||
bootstrap program, but additional initialization must be performed by
|
||
software before all the features of the processor can be utilized.
|
||
|
||
|
||
10.1 Processor State After Reset
|
||
|
||
The contents of EAX depend upon the results of the power-up self test. The
|
||
self-test may be requested externally by assertion of BUSY# at the end of
|
||
RESET. The EAX register holds zero if the 80386 passed the test. A nonzero
|
||
value in EAX after self-test indicates that the particular 80386 unit is
|
||
faulty. If the self-test is not requested, the contents of EAX after RESET
|
||
is undefined.
|
||
|
||
DX holds a component identifier and revision number after RESET as Figure
|
||
10-1 illustrates. DH contains 3, which indicates an 80386 component. DL
|
||
contains a unique identifier of the revision level.
|
||
|
||
Control register zero (CR0) contains the values shown in Figure 10-2. The
|
||
ET bit of CR0 is set if an 80387 is present in the configuration (according
|
||
to the state of the ERROR# pin after RESET). If ET is reset, the
|
||
configuration either contains an 80287 or does not contain a coprocessor. A
|
||
software test is required to distinguish between these latter two
|
||
possibilities.
|
||
|
||
The remaining registers and flags are set as follows:
|
||
|
||
EFLAGS =00000002H
|
||
IP =0000FFF0H
|
||
CS selector =000H
|
||
DS selector =0000H
|
||
ES selector =0000H
|
||
SS selector =0000H
|
||
FS selector =0000H
|
||
GS selector =0000H
|
||
IDTR:
|
||
base =0
|
||
limit =03FFH
|
||
|
||
All registers not mentioned above are undefined.
|
||
|
||
These settings imply that the processor begins in real-address mode with
|
||
interrupts disabled.
|
||
|
||
|
||
Figure 10-1. Contents of EDX after RESET
|
||
|
||
EDX REGISTER
|
||
|
||
31 23 15 7 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±³ DH ³ DL º
|
||
º±±±±±±±±±±±±UNDEFINED±±±±±±±±±±±±³ DEVICE ID ³ STEPPING ID º
|
||
º±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±³ 3 ³ (UNIQUE) º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
|
||
Figure 10-2. Initial Contents of CR0
|
||
|
||
CONTROL REGISTER ZERO
|
||
|
||
31 23 15 7 4 3 1 0
|
||
ÉÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÑÍÑÍÑÍÑÍÑÍ»
|
||
ºP³ ³E³T³E³M³Pº
|
||
º ³ UNDEFINED ³ ³ ³ ³ ³ º
|
||
ºG³ ³T³S³M³P³Eº
|
||
ÈÑÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÏÑÏÑÏÑÏÑÏѼ
|
||
³ ³ ³ ³ ³ ³
|
||
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄ0 - PAGING DISABLED ³ ³ ³ ³ ³
|
||
* - INDICATES PRESENCE OF 80387ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ ³ ³ ³
|
||
0 - NO TASK SWITCHÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ ³ ³
|
||
0 - DO NOT MONITOR COPROCESSORÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ ³
|
||
0 - COPROCESSOR NOT PRESENTÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³
|
||
0 - PROTECTION NOT ENABLED (REAL ADDRESS MODE)ÄÄÄÄÄÄÄÄÄÄÙ
|
||
|
||
|
||
10.2 Software Initialization for Real-Address Mode
|
||
|
||
In real-address mode a few structures must be initialized before a program
|
||
can take advantage of all the features available in this mode.
|
||
|
||
|
||
10.2.1 Stack
|
||
|
||
No instructions that use the stack can be used until the stack-segment
|
||
register (SS) has been loaded. SS must point to an area in RAM.
|
||
|
||
|
||
10.2.2 Interrupt Table
|
||
|
||
The initial state of the 80386 leaves interrupts disabled; however, the
|
||
processor will still attempt to access the interrupt table if an exception
|
||
or nonmaskable interrupt (NMI) occurs. Initialization software should take
|
||
one of the following actions:
|
||
|
||
þ Change the limit value in the IDTR to zero. This will cause a shutdown
|
||
if an exception or nonmaskable interrupt occurs. (Refer to the 80386
|
||
Hardware Reference Manual to see how shutdown is signalled externally.)
|
||
|
||
þ Put pointers to valid interrupt handlers in all positions of the
|
||
interrupt table that might be used by exceptions or interrupts.
|
||
|
||
þ Change the IDTR to point to a valid interrupt table.
|
||
|
||
|
||
10.2.3 First Instructions
|
||
|
||
After RESET, address lines A{31-20} are automatically asserted for
|
||
instruction fetches. This fact, together with the initial values of CS:IP,
|
||
causes instruction execution to begin at physical address FFFFFFF0H. Near
|
||
(intrasegment) forms of control transfer instructions may be used to pass
|
||
control to other addresses in the upper 64K bytes of the address space. The
|
||
first far (intersegment) JMP or CALL instruction causes A{31-20} to drop
|
||
low, and the 80386 continues executing instructions in the lower one
|
||
megabyte of physical memory. This automatic assertion of address lines
|
||
A{31-20} allows systems designers to use a ROM at the high end of
|
||
the address space to initialize the system.
|
||
|
||
|
||
10.3 Switching to Protected Mode
|
||
|
||
Setting the PE bit of the MSW in CR0 causes the 80386 to begin executing in
|
||
protected mode. The current privilege level (CPL) starts at zero. The
|
||
segment registers continue to point to the same linear addresses as in real
|
||
address mode (in real address mode, linear addresses are the same physical
|
||
addresses).
|
||
|
||
Immediately after setting the PE flag, the initialization code must flush
|
||
the processor's instruction prefetch queue by executing a JMP instruction.
|
||
The 80386 fetches and decodes instructions and addresses before they are
|
||
used; however, after a change into protected mode, the prefetched
|
||
instruction information (which pertains to real-address mode) is no longer
|
||
valid. A JMP forces the processor to discard the invalid information.
|
||
|
||
|
||
10.4 Software Initialization for Protected Mode
|
||
|
||
Most of the initialization needed for protected mode can be done either
|
||
before or after switching to protected mode. If done in protected mode,
|
||
however, the initialization procedures must not use protected-mode features
|
||
that are not yet initialized.
|
||
|
||
|
||
10.4.1 Interrupt Descriptor Table
|
||
|
||
The IDTR may be loaded in either real-address or protected mode. However,
|
||
the format of the interrupt table for protected mode is different than that
|
||
for real-address mode. It is not possible to change to protected mode and
|
||
change interrupt table formats at the same time; therefore, it is inevitable
|
||
that, if IDTR selects an interrupt table, it will have the wrong format at
|
||
some time. An interrupt or exception that occurs at this time will have
|
||
unpredictable results. To avoid this unpredictability, interrupts should
|
||
remain disabled until interrupt handlers are in place and a valid IDT has
|
||
been created in protected mode.
|
||
|
||
|
||
10.4.2 Stack
|
||
|
||
The SS register may be loaded in either real-address mode or protected
|
||
mode. If loaded in real-address mode, SS continues to point to the same
|
||
linear base-address after the switch to protected mode.
|
||
|
||
|
||
10.4.3 Global Descriptor Table
|
||
|
||
Before any segment register is changed in protected mode, the GDT register
|
||
must point to a valid GDT. Initialization of the GDT and GDTR may be done in
|
||
real-address mode. The GDT (as well as LDTs) should reside in RAM, because
|
||
the processor modifies the accessed bit of descriptors.
|
||
|
||
|
||
10.4.4 Page Tables
|
||
|
||
Page tables and the PDBR in CR3 can be initialized in either real-address
|
||
mode or in protected mode; however, the paging enabled (PG) bit of CR0
|
||
cannot be set until the processor is in protected mode. PG may be set
|
||
simultaneously with PE, or later. When PG is set, the PDBR in CR3 should
|
||
already be initialized with a physical address that points to a valid page
|
||
directory. The initialization procedure should adopt one of the following
|
||
strategies to ensure consistent addressing before and after paging is
|
||
enabled:
|
||
|
||
þ The page that is currently being executed should map to the same
|
||
physical addresses both before and after PG is set.
|
||
|
||
þ A JMP instruction should immediately follow the setting of PG.
|
||
|
||
|
||
10.4.5 First Task
|
||
|
||
The initialization procedure can run awhile in protected mode without
|
||
initializing the task register; however, before the first task switch, the
|
||
following conditions must prevail:
|
||
|
||
þ There must be a valid task state segment (TSS) for the new task. The
|
||
stack pointers in the TSS for privilege levels numerically less than or
|
||
equal to the initial CPL must point to valid stack segments.
|
||
|
||
þ The task register must point to an area in which to save the current
|
||
task state. After the first task switch, the information dumped in this
|
||
area is not needed, and the area can be used for other purposes.
|
||
|
||
|
||
10.5 Initialization Example
|
||
|
||
$TITLE ('Initial Task')
|
||
|
||
NAME INIT
|
||
|
||
init_stack SEGMENT RW
|
||
DW 20 DUP(?)
|
||
tos LABEL WORD
|
||
init_stack ENDS
|
||
|
||
init_data SEGMENT RW PUBLIC
|
||
DW 20 DUP(?)
|
||
init_data ENDS
|
||
|
||
init_code SEGMENT ER PUBLIC
|
||
|
||
ASSUME DS:init_data
|
||
|
||
nop
|
||
nop
|
||
nop
|
||
init_start:
|
||
; set up stack
|
||
mov ax, init_stack
|
||
mov ss, ax
|
||
mov esp, offset tos
|
||
|
||
mov a1,1
|
||
blink:
|
||
xor a1,1
|
||
out 0e4h,a1
|
||
mov cx,3FFFh
|
||
here:
|
||
dec cx
|
||
jnz here
|
||
|
||
jmp SHORT blink
|
||
|
||
hlt
|
||
init_code ends
|
||
|
||
END init_start, SS:init_stack, DS:init_data
|
||
|
||
$TITLE('Protected Mode Transition -- 386 initialization')
|
||
NAME RESET
|
||
|
||
;*****************************************************************
|
||
; Upon reset the 386 starts executing at address 0FFFFFFF0H. The
|
||
; upper 12 address bits remain high until a FAR call or jump is
|
||
; executed.
|
||
;
|
||
; Assume the following:
|
||
;
|
||
;
|
||
; - a short jump at address 0FFFFFFF0H (placed there by the
|
||
; system builder) causes execution to begin at START in segment
|
||
; RESET_CODE.
|
||
;
|
||
;
|
||
; - segment RESET_CODE is based at physical address 0FFFF0000H,
|
||
; i.e. at the start of the last 64K in the 4G address space.
|
||
; Note that this is the base of the CS register at reset. If
|
||
; you locate ROMcode above this address, you will need to
|
||
; figure out an adjustment factor to address things within this
|
||
; segment.
|
||
;
|
||
;*****************************************************************
|
||
$EJECT ;
|
||
|
||
; Define addresses to locate GDT and IDT in RAM.
|
||
; These addresses are also used in the BLD386 file that defines
|
||
; the GDT and IDT. If you change these addresses, make sure you
|
||
; change the base addresses specified in the build file.
|
||
|
||
GDTbase EQU 00001000H ; physical address for GDT base
|
||
IDTbase EQU 00000400H ; physical address for IDT base
|
||
|
||
PUBLIC GDT_EPROM
|
||
PUBLIC IDT_EPROM
|
||
PUBLIC START
|
||
|
||
DUMMY segment rw ; ONLY for ASM386 main module stack init
|
||
DW 0
|
||
DUMMY ends
|
||
|
||
;*****************************************************************
|
||
;
|
||
; Note: RESET CODE must be USEl6 because the 386 initally executes
|
||
; in real mode.
|
||
;
|
||
|
||
RESET_CODE segment er PUBLIC USE16
|
||
|
||
ASSUME DS:nothing, ES:nothing
|
||
|
||
;
|
||
; 386 Descriptor template
|
||
|
||
DESC STRUC
|
||
lim_0_15 DW 0 ; limit bits (0..15)
|
||
bas_0_15 DW 0 ; base bits (0..15)
|
||
bas_16_23 DB 0 ; base bits (16..23)
|
||
access DB 0 ; access byte
|
||
gran DB 0 ; granularity byte
|
||
bas_24_31 DB 0 ; base bits (24..31)
|
||
DESC ENDS
|
||
|
||
; The following is the layout of the real GDT created by BLD386.
|
||
; It is located in EPROM and will be copied to RAM.
|
||
;
|
||
; GDT[O] ... NULL
|
||
; GDT[1] ... Alias for RAM GDT
|
||
; GDT[2] ... Alias for RAM IDT
|
||
; GDT[2] ... initial task TSS
|
||
; GDT[3] ... initial task TSS alias
|
||
; GDT[4] ... initial task LDT
|
||
; GDT[5] ... initial task LDT alias
|
||
|
||
;
|
||
; define entries in GDT and IDT.
|
||
|
||
GDT_ENTRIES EQU 8
|
||
IDT_ENTRIES EQU 32
|
||
|
||
; define some constants to index into the real GDT
|
||
|
||
GDT_ALIAS EQU 1*SIZE DESC
|
||
IDT_ALIAS EQU 2*SIZE DESC
|
||
INIT_TSS EQU 3*SIZE DESC
|
||
INIT_TSS_A EQU 4*SIZE DESC
|
||
INIT_LDT EQU 5*SIZE DESC
|
||
INIT_LDT_A EQU 6*SIZE DESC
|
||
|
||
;
|
||
; location of alias in INIT_LDT
|
||
|
||
INIT_LDT_ALIAS EQU 1*SIZE DESC
|
||
|
||
;
|
||
; access rights byte for DATA and TSS descriptors
|
||
|
||
DS_ACCESS EQU 010010010B
|
||
TSS_ACCESS EQU 010001001B
|
||
|
||
|
||
;
|
||
; This temporary GDT will be used to set up the real GDT in RAM.
|
||
|
||
Temp_GDT LABEL BYTE ; tag for begin of scratch GDT
|
||
|
||
NULL_DES DESC <> ; NULL descriptor
|
||
|
||
; 32-Gigabyte data segment based at 0
|
||
FLAT_DES DESC <0FFFFH,0,0,92h,0CFh,0>
|
||
|
||
GDT_eprom DP ? ; Builder places GDT address and limit
|
||
; in this 6 byte area.
|
||
|
||
IDT_eprom DP ? ; Builder places IDT address and limit
|
||
; in this 6 byte area.
|
||
|
||
;
|
||
; Prepare operand for loadings GDTR and LDTR.
|
||
|
||
|
||
TGDT_pword LABEL PWORD ; for temp GDT
|
||
DW end_Temp_GDT_Temp_GDT -1
|
||
DD 0
|
||
|
||
GDT_pword LABEL PWORD ; for GDT in RAM
|
||
DW GDT_ENTRIES * SIZE DESC -1
|
||
DD GDTbase
|
||
|
||
IDT_pword LABEL PWORD ; for IDT in RAM
|
||
DW IDT_ENTRIES * SIZE DESC -1
|
||
DD IDTbase
|
||
|
||
|
||
end_Temp_GDT LABEL BYTE
|
||
|
||
;
|
||
; Define equates for addressing convenience.
|
||
|
||
GDT_DES_FLAT EQU DS:GDT_ALIAS +GDTbase
|
||
IDT_DES_FLAT EQU DS:IDT_ALIAS +GDTbase
|
||
|
||
INIT_TSS_A_OFFSET EQU DS:INIT_TSS_A
|
||
INIT_TSS_OFFSET EQU DS:INIT_TSS
|
||
|
||
INIT_LDT_A_OFFSET EQU DS:INIT_LDT_A
|
||
INIT_LDT_OFFSET EQU DS:INIT_LDT
|
||
|
||
|
||
; define pointer for first task switch
|
||
|
||
ENTRY POINTER LABEL DWORD
|
||
DW 0, INIT_TSS
|
||
|
||
;******************************************************************
|
||
;
|
||
; Jump from reset vector to here.
|
||
|
||
START:
|
||
|
||
CLI ;disable interrupts
|
||
CLD ;clear direction flag
|
||
|
||
LIDT NULL_des ;force shutdown on errors
|
||
|
||
;
|
||
; move scratch GDT to RAM at physical 0
|
||
|
||
XOR DI,DI
|
||
MOV ES,DI ;point ES:DI to physical location 0
|
||
|
||
|
||
MOV SI,OFFSET Temp_GDT
|
||
MOV CX,end_Temp_GDT-Temp_GDT ;set byte count
|
||
INC CX
|
||
;
|
||
; move table
|
||
|
||
REP MOVS BYTE PTR ES:[DI],BYTE PTR CS:[SI]
|
||
|
||
LGDT tGDT_pword ;load GDTR for Temp. GDT
|
||
;(located at 0)
|
||
|
||
; switch to protected mode
|
||
|
||
MOV EAX,CR0 ;get current CRO
|
||
MOV EAX,1 ;set PE bit
|
||
MOV CRO,EAX ;begin protected mode
|
||
;
|
||
; clear prefetch queue
|
||
|
||
JMP SHORT flush
|
||
flush:
|
||
|
||
; set DS,ES,SS to address flat linear space (0 ... 4GB)
|
||
|
||
MOV BX,FLAT_DES-Temp_GDT
|
||
MOV US,BX
|
||
MOV ES,BX
|
||
MOV SS,BX
|
||
;
|
||
; initialize stack pointer to some (arbitrary) RAM location
|
||
|
||
MOV ESP, OFFSET end_Temp_GDT
|
||
|
||
;
|
||
; copy eprom GDT to RAM
|
||
|
||
MOV ESI,DWORD PTR GDT_eprom +2 ; get base of eprom GDT
|
||
; (put here by builder).
|
||
|
||
MOV EDI,GDTbase ; point ES:EDI to GDT base in RAM.
|
||
|
||
MOV CX,WORD PTR gdt_eprom +0 ; limit of eprom GDT
|
||
INC CX
|
||
SHR CX,1 ; easier to move words
|
||
CLD
|
||
REP MOVS WORD PTR ES:[EDI],WORD PTR DS:[ESI]
|
||
|
||
;
|
||
; copy eprom IDT to RAM
|
||
;
|
||
MOV ESI,DWORD PTR IDT_eprom +2 ; get base of eprom IDT
|
||
; (put here by builder)
|
||
|
||
MOV EDI,IDTbase ; point ES:EDI to IDT base in RAM.
|
||
|
||
MOV CX,WORD PTR idt_eprom +0 ; limit of eprom IDT
|
||
INC CX
|
||
SHR CX,1
|
||
CLD
|
||
REP MOVS WORD PTR ES:[EDI],WORD PTR DS:[ESI]
|
||
|
||
; switch to RAM GDT and IDT
|
||
;
|
||
LIDT IDT_pword
|
||
LGDT GDT_pword
|
||
|
||
;
|
||
MOV BX,GDT_ALIAS ; point DS to GDT alias
|
||
MOV DS,BX
|
||
;
|
||
; copy eprom TSS to RAM
|
||
;
|
||
MOV BX,INIT_TSS_A ; INIT TSS A descriptor base
|
||
; has RAM location of INIT TSS.
|
||
|
||
MOV ES,BX ; ES points to TSS in RAM
|
||
|
||
MOV BX,INIT_TSS ; get inital task selector
|
||
LAR DX,BX ; save access byte
|
||
MOV [BX].access,DS_ACCESS ; set access as data segment
|
||
MOV FS,BX ; FS points to eprom TSS
|
||
|
||
XOR si,si ; FS:si points to eprom TSS
|
||
XOR di,di ; ES:di points to RAM TSS
|
||
|
||
MOV CX,[BX].lim_0_15 ; get count to move
|
||
INC CX
|
||
|
||
;
|
||
; move INIT_TSS to RAM.
|
||
|
||
REP MOVS BYTE PTR ES:[di],BYTE PTR FS:[si]
|
||
|
||
MOV [BX].access,DH ; restore access byte
|
||
|
||
;
|
||
; change base of INIT TSS descriptor to point to RAM.
|
||
|
||
MOV AX,INIT_TSS_A_OFFSET.bas_0_15
|
||
MOV INIT_TSS_OFFSET.bas_0_15,AX
|
||
MOV AL,INIT_TSS_A_OFFSET.bas_16_23
|
||
MOV INIT_TSS_OFFSET.bas_16_23,AL
|
||
MOV AL,INIT_TSS_A_OFFSET.bas_24_31
|
||
MOV INIT_TSS_OFFSET.bas_24_31,AL
|
||
|
||
;
|
||
; change INIT TSS A to form a save area for TSS on first task
|
||
; switch. Use RAM at location 0.
|
||
|
||
MOV BX,INIT_TSS_A
|
||
MOV WORD PTR [BX].bas_0_15,0
|
||
MOV [BX].bas_16_23,0
|
||
MOV [BX].bas_24_31,0
|
||
MOV [BX].access,TSS_ACCESS
|
||
MOV [BX].gran,O
|
||
LTR BX ; defines save area for TSS
|
||
|
||
;
|
||
; copy eprom LDT to RAM
|
||
|
||
MOV BX,INIT_LDT_A ; INIT_LDT_A descriptor has
|
||
; base address in RAM for INIT_LDT.
|
||
|
||
MOV ES,BX ; ES points LDT location in RAM.
|
||
|
||
MOV AH,[BX].bas_24_31
|
||
MOV AL,[BX].bas_16_23
|
||
SHL EAX,16
|
||
MOV AX,[BX].bas_0_15 ; save INIT_LDT base (ram) in EAX
|
||
|
||
MOV BX,INIT_LDT ; get inital LDT selector
|
||
LAR DX,BX ; save access rights
|
||
MOV [BX].access,DS_ACCESS ; set access as data segment
|
||
MOV FS,BX ; FS points to eprom LDT
|
||
|
||
XOR si,si ; FS:SI points to eprom LDT
|
||
XOR di,di ; ES:DI points to RAM LDT
|
||
|
||
MOV CX,[BX].lim_0_15 ; get count to move
|
||
INC CX
|
||
;
|
||
; move initial LDT to RAM
|
||
|
||
REP MOVS BYTE PTR ES:[di],BYTE PTR FS:[si]
|
||
|
||
MOV [BX].access,DH ; restore access rights in
|
||
; INIT_LDT descriptor
|
||
|
||
;
|
||
; change base of alias (of INIT_LDT) to point to location in RAM.
|
||
|
||
MOV ES:[INIT_LDT_ALIAS].bas_0_15,AX
|
||
SHR EAX,16
|
||
MOV ES:[INIT_LDT_ALIAS].bas_16_23,AL
|
||
MOV ES:[INIT_LDT_ALIAS].bas_24_31,AH
|
||
|
||
;
|
||
; now set the base value in INIT_LDT descriptor
|
||
|
||
MOV AX,INIT_LDT_A_OFFSET.bas_0_15
|
||
MOV INIT_LDT_OFFSET.bas_0_15,AX
|
||
MOV AL,INIT_LDT_A_OFFSET.bas_16_23
|
||
MOV INIT_LDT_OFFSET.bas_16_23,AL
|
||
MOV AL,INIT_LDT_A_OFFSET.bas_24_31
|
||
MOV INIT_LDT_OFFSET.bas_24_31,AL
|
||
|
||
;
|
||
; Now GDT, IDT, initial TSS and initial LDT are all set up.
|
||
;
|
||
; Start the first task!
|
||
'
|
||
JMP ENTRY_POINTER
|
||
|
||
RESET_CODE ends
|
||
END START, SS:DUMMY,DS:DUMMY
|
||
|
||
|
||
10.6 TLB Testing
|
||
|
||
The 80386 provides a mechanism for testing the Translation Lookaside Buffer
|
||
(TLB), the cache used for translating linear addresses to physical
|
||
addresses. Although failure of the TLB hardware is extremely unlikely, users
|
||
may wish to include TLB confidence tests among other power-up confidence
|
||
tests for the 80386.
|
||
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
NOTE
|
||
This TLB testing mechanism is unique to the 80386 and may not be
|
||
continued in the same way in future processors. Sortware that uses
|
||
this mechanism may be incompatible with future processors.
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
When testing the TLB it is recommended that paging be turned off (PG=0 in
|
||
CR0) to avoid interference with the test data being written to the TLB.
|
||
|
||
|
||
10.6.1 Structure of the TLB
|
||
|
||
The TLB is a four-way set-associative memory. Figure 10-3 illustrates the
|
||
structure of the TLB. There are four sets of eight entries each. Each entry
|
||
consists of a tag and data. Tags are 24-bits wide. They contain the
|
||
high-order 20 bits of the linear address, the valid bit, and three attribute
|
||
bits. The data portion of each entry contains the high-order 20 bits of the
|
||
physical address.
|
||
|
||
|
||
10.6.2 Test Registers
|
||
|
||
Two test registers, shown in Figure 10-4, are provided for the purpose of
|
||
testing. TR6 is the test command register, and TR7 is the test data
|
||
register. These registers are accessed by variants of the MOV
|
||
instruction. A test register may be either the source operand or destination
|
||
operand. The MOV instructions are defined in both real-address mode and
|
||
protected mode. The test registers are privileged resources; in protected
|
||
mode, the MOV instructions that access them can only be executed at
|
||
privilege level 0. An attempt to read or write the test registers when
|
||
executing at any other privilege level causes a general
|
||
protection exception.
|
||
|
||
The test command register (TR6) contains a command and an address tag to
|
||
use in performing the command:
|
||
|
||
C This is the command bit. There are two TLB testing commands:
|
||
write entries into the TLB, and perform TLB lookups. To cause an
|
||
immediate write into the TLB entry, move a doubleword into TR6
|
||
that contains a 0 in this bit. To cause an immediate TLB lookup,
|
||
move a doubleword into TR6 that contains a 1 in this bit.
|
||
|
||
Linear On a TLB write, a TLB entry is allocated to this linear address;
|
||
Address the rest of that TLB entry is set per the value of TR7 and the
|
||
value just written into TR6. On a TLB lookup, the TLB is
|
||
interrogated per this value; if one and only one TLB entry
|
||
matches, the rest of the fields of TR6 and TR7 are set from the
|
||
matching TLB entry.
|
||
|
||
V The valid bit for this TLB entry. The TLB uses the valid bit to
|
||
identify entries that contain valid data. Entries of the TLB
|
||
that have not been assigned values have zero in the valid bit.
|
||
All valid bits can be cleared by writing to CR3.
|
||
|
||
D, D# The dirty bit (and its complement) for/from the TLB entry.
|
||
|
||
U, U# The U/S bit (and its complement) for/from the TLB entry.
|
||
|
||
W, W# The R/W bit (and its complement) for/from the TLB entry.
|
||
|
||
The meaning of these pairs of bits is given by Table 10-1,
|
||
where X represents D, U, or W.
|
||
|
||
The test data register (TR7) holds data read from or data to be written to
|
||
the TLB.
|
||
|
||
Physical This is the data field of the TLB. On a write to the TLB, the
|
||
Address TLB entry allocated to the linear address in TR6 is set to this
|
||
value. On a TLB lookup, if HT is set, the data field (physical
|
||
address) from the TLB is read out to this field. If HT is not
|
||
set, this field is undefined.
|
||
|
||
HT For a TLB lookup, the HT bit indicates whether the lookup was a
|
||
hit (HT 1) or a miss (HT 0). For a TLB write, HT must be set
|
||
to 1.
|
||
|
||
REP For a TLB write, selects which of four associative blocks of the
|
||
TLB is to be written. For a TLB read, if HT is set, REP reports
|
||
in which of the four associative blocks the tag was found; if HT
|
||
is not set, REP is undefined.
|
||
|
||
|
||
Table 10-1. Meaning of D, U, and W Bit Pairs
|
||
|
||
X X# Effect during Value of bit X
|
||
TLB Lookup after TLB Write
|
||
|
||
0 0 (undefined) (undefined)
|
||
0 1 Match if X=0 Bit X becomes 0
|
||
1 0 Match if X=1 Bit X becomes 1
|
||
1 1 (undefined) (undefined)
|
||
|
||
|
||
Figure 10-3. TLB Structure
|
||
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
7º TAG º DATA º
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
|
||
ÚÄÄÄÄÄÄÄ
|
||
³ SET 11
|
||
³ ÚÄÄ ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
³ ³ 1º TAG º DATA º
|
||
³ ³ ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
³ ³ 0º TAG º DATA º
|
||
³ ³ ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
³ ³
|
||
³ ³ ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
³ ³ 7º TAG º DATA º
|
||
³ ³ ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
³ ³
|
||
³ ÀÄÄ
|
||
³ SET 10
|
||
³ ÚÄÄ ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
³ ³ 1º TAG º DATA º
|
||
³ D ³ ³ ³ ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
³ A ³ ³ ³ 0º TAG º DATA º
|
||
³ T ÀÄÄÄÄÄÄÙ ³ ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
³ A ³
|
||
³ ÚÄÄÄÄÄÄ¿ ³ ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
³ B ³ ³ ³ 7º TAG º DATA º
|
||
³ U ³ ³ ³ ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
³ S ³ ³ ³
|
||
³ ÀÄÄ
|
||
³ SET 01
|
||
³ ÚÄÄ ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
³ ³ 1º TAG º DATA º
|
||
³ ³ ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
³ ³ 0º TAG º DATA º
|
||
³ ³ ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
³ ³
|
||
³ ³ ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
³ ³ 7º TAG º DATA º
|
||
³ ³ ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
³ ³
|
||
³ ÀÄÄ
|
||
³ SET 00
|
||
ÀÄÄÄÄÄÄÄ ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
1º TAG º DATA º
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
0º TAG º DATA º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
|
||
Figure 10-4. Test Registers
|
||
|
||
31 23 15 11 7 0
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍØÍÍÍÍÍÍÍØÍÍÍÍÍÑÍÑÍÍÍÑÍÍÍ»
|
||
º ³ ³H³ ³ º
|
||
º PHYSICAL ADDRESS ³0 0 0 0 0 0 0³ ³REP³0 0º TR7
|
||
º ³ ³T³ ³ º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÂÄÂÄÂÄÂÄÂÄÂÄÅÄÁÄÄÄÁÄÂĶ
|
||
º ³ ³ ³D³ ³U³ ³W³ ³ º
|
||
º LINEAR ADDRESS ³V³D³ ³U³ ³ ³ ³0 0 0 0³Cº TR8
|
||
º ³ ³ ³#³ ³#³ ³#³ ³ º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍØÍÏÍÏÍÏÍØÍÏÍÏÍÏÍÍÍÍÍÍÍÏͼ
|
||
|
||
NOTE: 0 INDICATES INTEL RESERVED. NO NOT DEFINE
|
||
|
||
|
||
10.6.3 Test Operations
|
||
|
||
To write a TLB entry:
|
||
|
||
1. Move a doubleword to TR7 that contains the desired physical address,
|
||
HT, and REP values. HT must contain 1. REP must point to the
|
||
associative block in which to place the entry.
|
||
|
||
2. Move a doubleword to TR6 that contains the appropriate linear
|
||
address, and values for V, D, U, and W. Be sure C=0 for "write"
|
||
command.
|
||
|
||
Be careful not to write duplicate tags; the results of doing so are
|
||
undefined.
|
||
|
||
To look up (read) a TLB entry:
|
||
|
||
1. Move a doubleword to TR6 that contains the appropriate linear address
|
||
and attributes. Be sure C=1 for "lookup" command.
|
||
|
||
2. Store TR7. If the HT bit in TR7 indicates a hit, then the other
|
||
values reveal the TLB contents. If HT indicates a miss, then the other
|
||
values in TR7 are indeterminate.
|
||
|
||
For the purposes of testing, the V bit functions as another bit of
|
||
addresss. The V bit for a lookup request should usually be set, so that
|
||
uninitialized tags do not match. Lookups with V=0 are unpredictable if any
|
||
tags are uninitialized.
|
||
|
||
|
||
Chapter 11 Coprocessing and Multiprocessing
|
||
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
The 80386 has two levels of support for multiple parallel processing units:
|
||
|
||
þ A highly specialized interface for very closely coupled processors of
|
||
a type known as coprocessors.
|
||
|
||
þ A more general interface for more loosely coupled processors of
|
||
unspecified type.
|
||
|
||
|
||
11.1 Coprocessing
|
||
|
||
The components of the coprocessor interface include:
|
||
|
||
þ ET bit of control register zero (CR0)
|
||
þ The EM, and MP bits of CR0
|
||
þ The ESC instructions
|
||
þ The WAIT instruction
|
||
þ The TS bit of CR0
|
||
þ Exceptions
|
||
|
||
|
||
11.1.1 Coprocessor Identification
|
||
|
||
The 80386 is designed to operate with either an 80287 or 80387 math
|
||
coprocessor. The ET bit of CR0 indicates which type of coprocessor is
|
||
present. ET is set automatically by the 80386 after RESET according to the
|
||
level detected on the ERROR# input. If desired, ET may also be set or reset
|
||
by loading CR0 with a MOV instruction. If ET is set, the 80386 uses the
|
||
32-bit protocol of the 80387; if reset, the 80386 uses the 16-bit protocol
|
||
of the 80287.
|
||
|
||
|
||
11.1.2 ESC and WAIT Instructions
|
||
|
||
The 80386 interprets the pattern 11011B in the first five bits of an
|
||
instruction as an opcode intended for a coprocessor. Instructions thus
|
||
marked are called ESCAPE or ESC instructions. The CPU performs the following
|
||
functions upon encountering an ESC instruction before sending the
|
||
instruction to the coprocessor:
|
||
|
||
þ Tests the emulation mode (EM) flag to determine whether coprocessor
|
||
functions are being emulated by software.
|
||
|
||
þ Tests the TS flag to determine whether there has been a context change
|
||
since the last ESC instruction.
|
||
|
||
þ For some ESC instructions, tests the ERROR# pin to determine whether
|
||
the coprocessor detected an error in the previous ESC instruction.
|
||
|
||
The WAIT instruction is not an ESC instruction, but WAIT causes the CPU to
|
||
perform some of the same tests that it performs upon encountering an ESC
|
||
instruction. The processor performs the following actions for a WAIT
|
||
instruction:
|
||
|
||
þ Waits until the coprocessor no longer asserts the BUSY# pin.
|
||
|
||
þ Tests the ERROR# pin (after BUSY# goes inactive). If ERROR# is active,
|
||
the 80386 signals exception 16, which indicates that the coprocessor
|
||
encountered an error in the previous ESC instruction.
|
||
|
||
þ WAIT can therefore be used to cause exception 16 if an error is
|
||
pending from a previous ESC instruction. Note that, if no coprocessor
|
||
is present, the ERROR# and BUSY# pins should be tied inactive to
|
||
prevent WAIT from waiting forever or causing spurious exceptions.
|
||
|
||
|
||
11.1.3 EM and MP Flags
|
||
|
||
The EM and MP flags of CR0 control how the processor reacts to coprocessor
|
||
instructions.
|
||
|
||
The EM bit indicates whether coprocessor functions are to be emulated. If
|
||
the processor finds EM set when executing an ESC instruction, it signals
|
||
exception 7, giving the exception handler an opportunity to emulate the ESC
|
||
instruction.
|
||
|
||
The MP (monitor coprocessor) bit indicates whether a coprocessor is
|
||
actually attached. The MP flag controls the function of the WAIT
|
||
instruction. If, when executing a WAIT instruction, the CPU finds MP set,
|
||
then it tests the TS flag; it does not otherwise test TS during a WAIT
|
||
instruction. If it finds TS set under these conditions, the CPU signals
|
||
exception 7.
|
||
|
||
The EM and MP flags can be changed with the aid of a MOV instruction using
|
||
CR0 as the destination operand and read with the aid of a MOV instruction
|
||
with CR0 as the source operand. These forms of the MOV instruction can be
|
||
executed only at privilege level zero.
|
||
|
||
|
||
11.1.4 The Task-Switched Flag
|
||
|
||
The TS bit of CR0 helps to determine when the context of the coprocessor
|
||
does not match that of the task being executed by the 80386 CPU. The 80386
|
||
sets TS each time it performs a task switch (whether triggered by software
|
||
or by hardware interrupt). If, when interpreting one of the ESC
|
||
instructions, the CPU finds TS already set, it causes exception 7. The WAIT
|
||
instruction also causes exception 7 if both TS and MP are set. Operating
|
||
systems can use this exception to switch the context of the coprocessor to
|
||
correspond to the current task. Refer to the 80386 System Software Writer's
|
||
Guide for an example.
|
||
|
||
The CLTS instruction (legal only at privilege level zero) resets the TS
|
||
flag.
|
||
|
||
|
||
11.1.5 Coprocessor Exceptions
|
||
|
||
Three exceptions aid in interfacing to a coprocessor: interrupt 7
|
||
(coprocessor not available), interrupt 9 (coprocessor segment overrun), and
|
||
interrupt 16 (coprocessor error).
|
||
|
||
|
||
11.1.5.1 Interrupt 7 ÄÄ Coprocessor Not Available
|
||
|
||
This exception occurs in either of two conditions:
|
||
|
||
1. The CPU encounters an ESC instruction and EM is set. In this case,
|
||
the exception handler should emulate the instruction that caused the
|
||
exception. TS may also be set.
|
||
|
||
2. The CPU encounters either the WAIT instruction or an ESC instruction
|
||
when both MP and TS are set. In this case, the exception handler
|
||
should update the state of the coprocessor, if necessary.
|
||
|
||
|
||
11.1.5.2 Interrupt 9 ÄÄ Coprocessor Segment Overrun
|
||
|
||
This exception occurs in protected mode under the following conditions:
|
||
|
||
þ An operand of a coprocessor instruction wraps around an addressing
|
||
limit (0FFFFH for small segments, 0FFFFFFFFH for big segments, zero for
|
||
expand-down segments). An operand may wrap around an addressing limit
|
||
when the segment limit is near an addressing limit and the operand is
|
||
near the largest valid address in the segment. Because of the
|
||
wrap-around, the beginning and ending addresses of such an operand
|
||
will be near opposite ends of the segment.
|
||
|
||
þ Both the first byte and the last byte of the operand (considering
|
||
wrap-around) are at addresses located in the segment and in present and
|
||
accessible pages.
|
||
|
||
þ The operand spans inaccessible addresses. There are two ways that such
|
||
an operand may also span inaccessible addresses:
|
||
|
||
1. The segment limit is not equal to the addressing limit (e.g.,
|
||
addressing limit is FFFFH and segment limit is FFFDH); therefore,
|
||
the operand will span addresses that are not within the segment
|
||
(e.g., an 8-byte operand that starts at valid offset FFFC will span
|
||
addresses FFFC-FFFF and 0000-0003; however, addresses FFFE and FFFF
|
||
are not valid, because they exceed the limit);
|
||
|
||
2. The operand begins and ends in present and accessible pages but
|
||
intermediate bytes of the operand fall either in a not-present page
|
||
or in a page to which the current procedure does not have access
|
||
rights.
|
||
|
||
The address of the failing numerics instruction and data operand may be
|
||
lost; an FSTENV does not return reliable addresses. As with the 80286/80287,
|
||
the segment overrun exception should be handled by executing an FNINIT
|
||
instruction (i.e., an FINIT without a preceding WAIT). The return address on
|
||
the stack does not necessarily point to the failing instruction nor to the
|
||
following instruction. The failing numerics instruction is not restartable.
|
||
|
||
Case 2 can be avoided by either aligning all segments on page boundaries or
|
||
by not starting them within 108 bytes of the start or end of a page. (The
|
||
maximum size of a coprocessor operand is 108 bytes.) Case 1 can be avoided
|
||
by making sure that the gap between the last valid offset and the first
|
||
valid offset of a segment is either no less than 108 bytes or is zero (i.e.,
|
||
the segment is of full size). If neither software system design constraint
|
||
is acceptable, the exception handler should execute FNINIT and should
|
||
probably terminate the task.
|
||
|
||
|
||
11.1.5.3 Interrupt 16 ÄÄ Coprocessor Error
|
||
|
||
The numerics coprocessors can detect six different exception conditions
|
||
during instruction execution. If the detected exception is not masked by a
|
||
bit in the control word, the coprocessor communicates the fact that an error
|
||
occurred to the CPU by a signal at the ERROR# pin. The CPU causes interrupt
|
||
16 the next time it checks the ERROR# pin, which is only at the beginning of
|
||
a subsequent WAIT or certain ESC instructions. If the exception is masked,
|
||
the numerics coprocessor handles the exception according to on-board logic;
|
||
it does not assert the ERROR# pin in this case.
|
||
|
||
|
||
11.2 General Multiprocessing
|
||
|
||
The components of the general multiprocessing interface include:
|
||
|
||
þ The LOCK# signal
|
||
|
||
þ The LOCK instruction prefix, which gives programmed control of the
|
||
LOCK# signal.
|
||
|
||
þ Automatic assertion of the LOCK# signal with implicit memory updates
|
||
by the processor
|
||
|
||
|
||
11.2.1 LOCK and the LOCK# Signal
|
||
|
||
The LOCK instruction prefix and its corresponding output signal LOCK# can
|
||
be used to prevent other bus masters from interrupting a data movement
|
||
operation. LOCK may only be used with the following 80386 instructions when
|
||
they modify memory. An undefined-opcode exception results from using LOCK
|
||
before any instruction other than:
|
||
|
||
þ Bit test and change: BTS, BTR, BTC.
|
||
þ Exchange: XCHG.
|
||
þ Two-operand arithmetic and logical: ADD, ADC, SUB, SBB, AND, OR, XOR.
|
||
þ One-operand arithmetic and logical: INC, DEC, NOT, and NEG.
|
||
|
||
A locked instruction is only guaranteed to lock the area of memory defined
|
||
by the destination operand, but it may lock a larger memory area. For
|
||
example, typical 8086 and 80286 configurations lock the entire physical
|
||
memory space. The area of memory defined by the destination operand is
|
||
guaranteed to be locked against access by a processor executing a locked
|
||
instruction on exactly the same memory area, i.e., an operand with
|
||
identical starting address and identical length.
|
||
|
||
The integrity of the lock is not affected by the alignment of the memory
|
||
field. The LOCK signal is asserted for as many bus cycles as necessary to
|
||
update the entire operand.
|
||
|
||
|
||
11.2.2 Automatic Locking
|
||
|
||
In several instances, the processor itself initiates activity on the data
|
||
bus. To help ensure that such activities function correctly in
|
||
multiprocessor configurations, the processor automatically asserts the LOCK#
|
||
signal. These instances include:
|
||
|
||
þ Acknowledging interrupts.
|
||
|
||
After an interrupt request, the interrupt controller uses the data bus
|
||
to send the interrupt ID of the interrupt source to the CPU. The CPU
|
||
asserts LOCK# to ensure that no other data appears on the data bus
|
||
during this time.
|
||
|
||
þ Setting busy bit of TSS descriptor.
|
||
|
||
The processor tests and sets the busy-bit in the type field of the TSS
|
||
descriptor when switching to a task. To ensure that two different
|
||
processors cannot simultaneously switch to the same task, the processor
|
||
asserts LOCK# while testing and setting this bit.
|
||
|
||
þ Loading of descriptors.
|
||
|
||
While copying the contents of a descriptor from a descriptor table into
|
||
a segment register, the processor asserts LOCK# so that the descriptor
|
||
cannot be modified by another processor while it is being loaded. For
|
||
this action to be effective, operating-system procedures that update
|
||
descriptors should adhere to the following steps:
|
||
|
||
ÄÄ Use a locked update to the access-rights byte to mark the
|
||
descriptor not-present.
|
||
|
||
ÄÄ Update the fields of the descriptor. (This may require several
|
||
memory accesses; therefore, LOCK cannot be used.)
|
||
|
||
ÄÄ Use a locked update to the access-rights byte to mark the
|
||
descriptor present again.
|
||
|
||
þ Updating page-table A and D bits.
|
||
|
||
The processor exerts LOCK# while updating the A (accessed) and D
|
||
(dirty) bits of page-table entries. Also the processor bypasses the
|
||
page-table cache and directly updates these bits in memory.
|
||
|
||
þ Executing XCHG instruction.
|
||
|
||
The 80386 always asserts LOCK during an XCHG instruction that
|
||
references memory (even if the LOCK prefix is not used).
|
||
|
||
|
||
11.2.3 Cache Considerations
|
||
|
||
Systems programmers must take care when updating shared data that may also
|
||
be stored in on-chip registers and caches. With the 80386, such shared
|
||
data includes:
|
||
|
||
þ Descriptors, which may be held in segment registers.
|
||
|
||
A change to a descriptor that is shared among processors should be
|
||
broadcast to all processors. Segment registers are effectively
|
||
"descriptor caches". A change to a descriptor will not be utilized by
|
||
another processor if that processor already has a copy of the old
|
||
version of the descriptor in a segment register.
|
||
|
||
þ Page tables, which may be held in the page-table cache.
|
||
|
||
A change to a page table that is shared among processors should be
|
||
broadcast to all processors, so that others can flush their page-table
|
||
caches and reload them with up-to-date page tables from memory.
|
||
|
||
Systems designers can employ an interprocessor interrupt to handle the
|
||
above cases. When one processor changes data that may be cached by other
|
||
processors, it can send an interrupt signal to all other processors that may
|
||
be affected by the change. If the interrupt is serviced by an interrupt
|
||
task, the task switch automatically flushes the segment registers. The task
|
||
switch also flushes the page-table cache if the PDBR (the contents of CR3)
|
||
of the interrupt task is different from the PDBR of every other task.
|
||
|
||
In multiprocessor systems that need a cacheability signal from the CPU, it
|
||
is recommended that physical address pin A31 be used to indicate
|
||
cacheability. Such a system can then possess up to 2 Gbytes of physical
|
||
memory. The virtual address range available to the programmer is not
|
||
affected by this convention.
|
||
|
||
|
||
Chapter 12 Debugging
|
||
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
The 80386 brings to Intel's line of microprocessors significant advances in
|
||
debugging power. The single-step exception and breakpoint exception of
|
||
previous processors are still available in the 80386, but the principal
|
||
debugging support takes the form of debug registers. The debug registers
|
||
support both instruction breakpoints and data breakpoints. Data breakpoints
|
||
are an important innovation that can save hours of debugging time by
|
||
pinpointing, for example, exactly when a data structure is being
|
||
overwritten. The breakpoint registers also eliminate the complexities
|
||
associated with writing a breakpoint instruction into a code segment
|
||
(requires a data-segment alias for the code segment) or a code segment
|
||
shared by multiple tasks (the breakpoint exception can occur in the context
|
||
of any of the tasks). Breakpoints can even be set in code contained in ROM.
|
||
|
||
|
||
12.1 Debugging Features of the Architecture
|
||
|
||
The features of the 80386 architecture that support debugging include:
|
||
|
||
Reserved debug interrupt vector
|
||
|
||
Permits processor to automatically invoke a debugger task or procedure when
|
||
an event occurs that is of interest to the debugger.
|
||
|
||
Four debug address registers
|
||
|
||
Permit programmers to specify up to four addresses that the CPU will
|
||
automatically monitor.
|
||
|
||
Debug control register
|
||
|
||
Allows programmers to selectively enable various debug conditions
|
||
associated with the four debug addresses.
|
||
|
||
Debug status register
|
||
|
||
Helps debugger identify condition that caused debug exception.
|
||
|
||
Trap bit of TSS (T-bit)
|
||
|
||
Permits monitoring of task switches.
|
||
|
||
Resume flag (RF) of flags register
|
||
|
||
Allows an instruction to be restarted after a debug exception without
|
||
immediately causing another debug exception due to the same condition.
|
||
|
||
Single-step flag (TF)
|
||
|
||
Allows complete monitoring of program flow by specifying whether the CPU
|
||
should cause a debug exception with the execution of every instruction.
|
||
|
||
Breakpoint instruction
|
||
|
||
Permits debugger intervention at any point in program execution and aids
|
||
debugging of debugger programs.
|
||
|
||
Reserved interrupt vector for breakpoint exception
|
||
|
||
Permits processor to automatically invoke a handler task or procedure upon
|
||
encountering a breakpoint instruction.
|
||
|
||
These features make it possible to invoke a debugger that is either a
|
||
separate task or a procedure in the context of the current task. The
|
||
debugger can be invoked under any of the following kinds of conditions:
|
||
|
||
þ Task switch to a specific task.
|
||
þ Execution of the breakpoint instruction.
|
||
þ Execution of every instruction.
|
||
þ Execution of any instruction at a given address.
|
||
þ Read or write of a byte, word, or doubleword at any specified address.
|
||
þ Write to a byte, word, or doubleword at any specified address.
|
||
þ Attempt to change a debug register.
|
||
|
||
|
||
12.2 Debug Registers
|
||
|
||
Six 80386 registers are used to control debug features. These registers are
|
||
accessed by variants of the MOV instruction. A debug register may be either
|
||
the source operand or destination operand. The debug registers are
|
||
privileged resources; the MOV instructions that access them can only be
|
||
executed at privilege level zero. An attempt to read or write the debug
|
||
registers when executing at any other privilege level causes a general
|
||
protection exception. Figure 12-1 shows the format of the debug registers.
|
||
|
||
|
||
Figure 12-1. Debug Registers
|
||
|
||
31 23 15 7 0
|
||
ÉÍÍÍÑÍÍÍÑÍÍÍÑÍÍÍØÍÍÍÑÍÍÍÑÍÍÍÑÍÍÍØÍÍÍÑÍÑÍÍÍÍÍÑÍÑÍØÍÑÍÑÍÑÍÑÍÑÍÑÍÑÍ»
|
||
ºLEN³R/W³LEN³R/W³LEN³R/W³LEN³R/W³ ³ ³ ³G³L³G³L³G³L³G³L³G³Lº
|
||
º ³ ³ ³ ³ ³ ³ ³ ³0 0³0³0 0 0³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º DR7
|
||
º 3 ³ 3 ³ 2 ³ 2 ³ 1 ³ 1 ³ 0 ³ 0 ³ ³ ³ ³E³E³3³3³2³2³1³1³0³0º
|
||
ÇÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÅÄÂÄÅÄÅÄÄÄÄÄÁÄÁÄÁÄÁÄÁÄÁÄÅÄÅÄÅÄÅĶ
|
||
º ³B³B³B³ ³B³B³B³Bº
|
||
º0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0³ ³ ³ ³0 0 0 0 0 0 0 0 0³ ³ ³ ³ º DR6
|
||
º ³T³S³D³ ³3³2³1³0º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÁÄÁÄÁÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÁÄÁÄÁÄÁĶ
|
||
º º
|
||
º RESERVED º DR5
|
||
º º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º º
|
||
º RESERVED º DR4
|
||
º º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º º
|
||
º BREAKPOINT 3 LINEAR ADDRESS º DR3
|
||
º º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º º
|
||
º BREAKPOINT 2 LINEAR ADDRESS º DR2
|
||
º º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º º
|
||
º BREAKPOINT 1 LINEAR ADDRESS º DR1
|
||
º º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º º
|
||
º BREAKPOINT 0 LINEAR ADDRESS º DR0
|
||
º º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
NOTE
|
||
0 MEANS INTEL RESERVED. DO NOT DEFINE.
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
|
||
12.2.1 Debug Address Registers (DR0-DR3)
|
||
|
||
Each of these registers contains the linear address associated with one of
|
||
four breakpoint conditions. Each breakpoint condition is further defined by
|
||
bits in DR7.
|
||
|
||
The debug address registers are effective whether or not paging is enabled.
|
||
The addresses in these registers are linear addresses. If paging is enabled,
|
||
the linear addresses are translated into physical addresses by the
|
||
processor's paging mechanism (as explained in Chapter 5). If paging is not
|
||
enabled, these linear addresses are the same as physical addresses.
|
||
|
||
Note that when paging is enabled, different tasks may have different
|
||
linear-to-physical address mappings. When this is the case, an address in a
|
||
debug address register may be relevant to one task but not to another. For
|
||
this reason the 80386 has both global and local enable bits in DR7. These
|
||
bits indicate whether a given debug address has a global (all tasks) or
|
||
local (current task only) relevance.
|
||
|
||
|
||
12.2.2 Debug Control Register (DR7)
|
||
|
||
The debug control register shown in Figure 12-1 both helps to define the
|
||
debug conditions and selectively enables and disables those conditions.
|
||
|
||
For each address in registers DR0-DR3, the corresponding fields R/W0
|
||
through R/W3 specify the type of action that should cause a breakpoint. The
|
||
processor interprets these bits as follows:
|
||
|
||
00 ÄÄ Break on instruction execution only
|
||
01 ÄÄ Break on data writes only
|
||
10 ÄÄ undefined
|
||
11 ÄÄ Break on data reads or writes but not instruction fetches
|
||
|
||
Fields LEN0 through LEN3 specify the length of data item to be monitored. A
|
||
length of 1, 2, or 4 bytes may be specified. The values of the length fields
|
||
are interpreted as follows:
|
||
|
||
00 ÄÄ one-byte length
|
||
01 ÄÄ two-byte length
|
||
10 ÄÄ undefined
|
||
11 ÄÄ four-byte length
|
||
|
||
If RWn is 00 (instruction execution), then LENn should also be 00. Any other
|
||
length is undefined.
|
||
|
||
The low-order eight bits of DR7 (L0 through L3 and G0 through G3)
|
||
selectively enable the four address breakpoint conditions. There are two
|
||
levels of enabling: the local (L0 through L3) and global (G0 through G3)
|
||
levels. The local enable bits are automatically reset by the processor at
|
||
every task switch to avoid unwanted breakpoint conditions in the new task.
|
||
The global enable bits are not reset by a task switch; therefore, they can
|
||
be used for conditions that are global to all tasks.
|
||
|
||
The LE and GE bits control the "exact data breakpoint match" feature of the
|
||
processor. If either LE or GE is set, the processor slows execution so that
|
||
data breakpoints are reported on the instruction that causes them. It is
|
||
recommended that one of these bits be set whenever data breakpoints are
|
||
armed. The processor clears LE at a task switch but does not clear GE.
|
||
|
||
|
||
12.2.3 Debug Status Register (DR6)
|
||
|
||
The debug status register shown in Figure 12-1 permits the debugger to
|
||
determine which debug conditions have occurred.
|
||
|
||
When the processor detects an enabled debug exception, it sets the
|
||
low-order bits of this register (B0 thru B3) before entering the debug
|
||
exception handler. Bn is set if the condition described by DRn, LENn, and
|
||
R/Wn occurs. (Note that the processor sets Bn regardless of whether Gn or
|
||
Ln is set. If more than one breakpoint condition occurs at one time and if
|
||
the breakpoint trap occurs due to an enabled condition other than n, Bn may
|
||
be set, even though neither Gn nor Ln is set.)
|
||
|
||
The BT bit is associated with the T-bit (debug trap bit) of the TSS (refer
|
||
to 7 for the location of the T-bit). The processor sets the BT bit before
|
||
entering the debug handler if a task switch has occurred and the T-bit of
|
||
the new TSS is set. There is no corresponding bit in DR7 that enables and
|
||
disables this trap; the T-bit of the TSS is the sole enabling bit.
|
||
|
||
The BS bit is associated with the TF (trap flag) bit of the EFLAGS
|
||
register. The BS bit is set if the debug handler is entered due to the
|
||
occurrence of a single-step exception. The single-step trap is the
|
||
highest-priority debug exception; therefore, when BS is set, any of the
|
||
other debug status bits may also be set.
|
||
|
||
The BD bit is set if the next instruction will read or write one of the
|
||
eight debug registers and ICE-386 is also using the debug registers at the
|
||
same time.
|
||
|
||
Note that the bits of DR6 are never cleared by the processor. To avoid any
|
||
confusion in identifying the next debug exception, the debug handler should
|
||
move zeros to DR6 immediately before returning.
|
||
|
||
|
||
12.2.4 Breakpoint Field Recognition
|
||
|
||
The linear address and LEN field for each of the four breakpoint conditions
|
||
define a range of sequential byte addresses for a data breakpoint. The LEN
|
||
field permits specification of a one-, two-, or four-byte field. Two-byte
|
||
fields must be aligned on word boundaries (addresses that are multiples of
|
||
two) and four-byte fields must be aligned on doubleword boundaries
|
||
(addresses that are multiples of four). These requirements are enforced by
|
||
the processor; it uses the LEN bits to mask the low-order bits of the
|
||
addresses in the debug address registers. Improperly aligned code or data
|
||
breakpoint addresses will not yield the expected results.
|
||
|
||
A data read or write breakpoint is triggered if any of the bytes
|
||
participating in a memory access is within the field defined by a breakpoint
|
||
address register and the corresponding LEN field. Table 12-1 gives some
|
||
examples of breakpoint fields with memory references that both do and do not
|
||
cause traps.
|
||
|
||
To set a data breakpoint for a misaligned field longer than one byte, it
|
||
may be desirable to put two sets of entries in the breakpoint register such
|
||
that each entry is properly aligned and the two entries together span the
|
||
length of the field.
|
||
|
||
Instruction breakpoint addresses must have a length specification of one
|
||
byte (LEN = 00); other values are undefined. The processor recognizes an
|
||
instruction breakpoint address only when it points to the first byte of an
|
||
instruction. If the instruction has any prefixes, the breakpoint address
|
||
must point to the first prefix.
|
||
|
||
|
||
Table 12-1. Breakpoint Field Recognition Examples
|
||
|
||
Address (hex) Length
|
||
|
||
DR0 0A0001 1 (LEN0 = 00)
|
||
Register Contents DR1 0A0002 1 (LEN1 = 00)
|
||
DR2 0B0002 2 (LEN2 = 01)
|
||
DR3 0C0000 4 (LEN3 = 11)
|
||
|
||
Some Examples of Memory 0A0001 1
|
||
References That Cause Traps 0A0002 1
|
||
0A0001 2
|
||
0A0002 2
|
||
0B0002 2
|
||
0B0001 4
|
||
0C0000 4
|
||
0C0001 2
|
||
0C0003 1
|
||
|
||
Some Examples of Memory 0A0000 1
|
||
References That Don't Cause Traps 0A0003 4
|
||
0B0000 2
|
||
0C0004 4
|
||
|
||
|
||
12.3 Debug Exceptions
|
||
|
||
Two of the interrupt vectors of the 80386 are reserved for exceptions that
|
||
relate to debugging. Interrupt 1 is the primary means of invoking debuggers
|
||
designed expressly for the 80386; interrupt 3 is intended for debugging
|
||
debuggers and for compatibility with prior processors in Intel's 8086
|
||
processor family.
|
||
|
||
|
||
12.3.1 Interrupt 1 ÄÄ Debug Exceptions
|
||
|
||
The handler for this exception is usually a debugger or part of a debugging
|
||
system. The processor causes interrupt 1 for any of several conditions. The
|
||
debugger can check flags in DR6 and DR7 to determine what condition caused
|
||
the exception and what other conditions might be in effect at the same time.
|
||
Table 12-2 associates with each breakpoint condition the combination of
|
||
bits that indicate when that condition has caused the debug exception.
|
||
|
||
Instruction address breakpoint conditions are faults, while other debug
|
||
conditions are traps. The debug exception may report either or both at one
|
||
time. The following paragraphs present details for each class of debug
|
||
exception.
|
||
|
||
|
||
Table 12-2. Debug Exception Conditions
|
||
|
||
Flags to Test Condition
|
||
|
||
BS=1 Single-step trap
|
||
B0=1 AND (GE0=1 OR LE0=1) Breakpoint DR0, LEN0, R/W0
|
||
B1=1 AND (GE1=1 OR LE1=1) Breakpoint DR1, LEN1, R/W1
|
||
B2=1 AND (GE2=1 OR LE2=1) Breakpoint DR2, LEN2, R/W2
|
||
B3=1 AND (GE3=1 OR LE3=1) Breakpoint DR3, LEN3, R/W3
|
||
BD=1 Debug registers not available; in use by ICE-386.
|
||
BT=1 Task switch
|
||
|
||
|
||
12.3.1.1 Instruction Addrees Breakpoint
|
||
|
||
The processor reports an instruction-address breakpoint before it executes
|
||
the instruction that begins at the given address; i.e., an instruction-
|
||
address breakpoint exception is a fault.
|
||
|
||
The RF (restart flag) permits the debug handler to retry instructions that
|
||
cause other kinds of faults in addition to debug faults. When it detects a
|
||
fault, the processor automatically sets RF in the flags image that it pushes
|
||
onto the stack. (It does not, however, set RF for traps and aborts.)
|
||
|
||
When RF is set, it causes any debug fault to be ignored during the next
|
||
instruction. (Note, however, that RF does not cause breakpoint traps to be
|
||
ignored, nor other kinds of faults.)
|
||
|
||
The processor automatically clears RF at the successful completion of every
|
||
instruction except after the IRET instruction, after the POPF instruction,
|
||
and after a JMP, CALL, or INT instruction that causes a task switch. These
|
||
instructions set RF to the value specified by the memory image of the EFLAGS
|
||
register.
|
||
|
||
The processor automatically sets RF in the EFLAGS image on the stack before
|
||
entry into any fault handler. Upon entry into the fault handler for
|
||
instruction address breakpoints, for example, RF is set in the EFLAGS image
|
||
on the stack; therefore, the IRET instruction at the end of the handler will
|
||
set RF in the EFLAGS register, and execution will resume at the breakpoint
|
||
address without generating another breakpoint fault at the same address.
|
||
|
||
If, after a debug fault, RF is set and the debug handler retries the
|
||
faulting instruction, it is possible that retrying the instruction will
|
||
raise other faults. The retry of the instruction after these faults will
|
||
also be done with RF=1, with the result that debug faults continue to be
|
||
ignored. The processor clears RF only after successful completion of the
|
||
instruction.
|
||
|
||
Real-mode debuggers can control the RF flag by using a 32-bit IRET. A
|
||
16-bit IRET instruction does not affect the RF bit (which is in the
|
||
high-order 16 bits of EFLAGS). To use a 32-bit IRET, the debugger must
|
||
rearrange the stack so that it holds appropriate values for the 32-bit EIP,
|
||
CS, and EFLAGS (with RF set in the EFLAGS image). Then executing an IRET
|
||
with an operand size prefix causes a 32-bit return, popping the RF flag
|
||
into EFLAGS.
|
||
|
||
|
||
12.3.1.2 Data Address Breakpoint
|
||
|
||
A data-address breakpoint exception is a trap; i.e., the processor reports
|
||
a data-address breakpoint after executing the instruction that accesses the
|
||
given memory item.
|
||
|
||
When using data breakpoints it is recommended that either the LE or GE bit
|
||
of DR7 be set also. If either LE or GE is set, any data breakpoint trap is
|
||
reported exactly after completion of the instruction that accessed the
|
||
specified memory item. This exact reporting is accomplished by forcing the
|
||
80386 execution unit to wait for completion of data operand transfers before
|
||
beginning execution of the next instruction. If neither GE nor LE is set,
|
||
data breakpoints may not be reported until one instruction after the data is
|
||
accessed or may not be reported at all. This is due to the fact that,
|
||
normally, instruction execution is overlapped with memory transfers to such
|
||
a degree that execution of the next instruction may begin before memory
|
||
transfers for the prior instruction are completed.
|
||
|
||
If a debugger needs to preserve the contents of a write breakpoint
|
||
location, it should save the original contents before setting a write
|
||
breakpoint. Because data breakpoints are traps, a write into a breakpoint
|
||
location will complete before the trap condition is reported. The handler
|
||
can report the saved value after the breakpoint is triggered. The data in
|
||
the debug registers can be used to address the new value stored by the
|
||
instruction that triggered the breakpoint.
|
||
|
||
|
||
12.3.1.3 General Detect Fault
|
||
|
||
This exception occurs when an attempt is made to use the debug registers at
|
||
the same time that ICE-386 is using them. This additional protection feature
|
||
is provided to guarantee that ICE-386 can have full control over the
|
||
debug-register resources when required. ICE-386 uses the debug-registers;
|
||
therefore, a software debugger that also uses these registers cannot run
|
||
while ICE-386 is in use. The exception handler can detect this condition by
|
||
examining the BD bit of DR6.
|
||
|
||
|
||
12.3.1.4 Single-Step Trap
|
||
|
||
This debug condition occurs at the end of an instruction if the trap flag
|
||
(TF) of the flags register held the value one at the beginning of that
|
||
instruction. Note that the exception does not occur at the end of an
|
||
instruction that sets TF. For example, if POPF is used to set TF, a
|
||
single-step trap does not occur until after the instruction that follows
|
||
POPF.
|
||
|
||
The processor clears the TF bit before invoking the handler. If TF=1 in
|
||
the flags image of a TSS at the time of a task switch, the exception occurs
|
||
after the first instruction is executed in the new task.
|
||
|
||
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 INTO
|
||
rather than executing them directly.
|
||
|
||
To maintain protection, system software should check the current execution
|
||
privilege level after any single step interrupt to see whether single
|
||
stepping should continue at the current privilege level.
|
||
|
||
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. To single step an interrupt handler, just single step an INT
|
||
n instruction that refers to the interrupt handler.
|
||
|
||
|
||
12.3.1.5 Task Switch Breakpoint
|
||
|
||
The debug exception also occurs after a switch to an 80386 task if the
|
||
T-bit of the new TSS is set. The exception occurs after control has passed
|
||
to the new task, but before the first instruction of that task is executed.
|
||
The exception handler can detect this condition by examining the BT bit of
|
||
the debug status register DR6.
|
||
|
||
Note that if the debug exception handler is a task, the T-bit of its TSS
|
||
should not be set. Failure to observe this rule will cause the processor to
|
||
enter an infinite loop.
|
||
|
||
|
||
12.3.2 Interrupt 3 ÄÄ Breakpoint Exception
|
||
|
||
This exception is caused by execution of the breakpoint instruction INT 3.
|
||
Typically, a debugger prepares a breakpoint by substituting the opcode of
|
||
the one-byte breakpoint instruction in place of the first opcode byte of the
|
||
instruction to be trapped. When execution of the INT 3 instruction causes
|
||
the exception handler to be invoked, the saved value of ES:EIP points to the
|
||
byte following the INT 3 instruction.
|
||
|
||
With prior generations of processors, this feature is used extensively for
|
||
trapping execution of specific instructions. With the 80386, the needs
|
||
formerly filled by this feature are more conveniently solved via the debug
|
||
registers and interrupt 1. However, the breakpoint exception is still
|
||
useful for debugging debuggers, because the breakpoint exception can vector
|
||
to a different exception handler than that used by the debugger. The
|
||
breakpoint exception can also be useful when it is necessary to set a
|
||
greater number of breakpoints than permitted by the debug registers. |