20855 lines
837 KiB
Plaintext
20855 lines
837 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³1³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.
|
|
|
|
|
|
PART III COMPATIBILITY
|
|
|
|
|
|
Chapter 13 Executing 80286 Protected-Mode Code
|
|
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
|
|
13.1 80286 Code Executes as a Subset of the 80386
|
|
|
|
In general, programs designed for execution in protected mode on an 80286
|
|
execute without modification on the 80386, because the features of the 80286
|
|
are a subset of those of the 80386.
|
|
|
|
All the descriptors used by the 80286 are supported by the 80386 as long as
|
|
the Intel-reserved word (last word) of the 80286 descriptor is zero.
|
|
|
|
The descriptors for data segments, executable segments, local descriptor
|
|
tables, and task gates are common to both the 80286 and the 80386. Other
|
|
80286 descriptorsÄÄTSS segment, call gate, interrupt gate, and trap
|
|
gateÄÄare supported by the 80386. The 80386 also has new versions of
|
|
descriptors for TSS segment, call gate, interrupt gate, and trap gate that
|
|
support the 32-bit nature of the 80386. Both sets of descriptors can be
|
|
used simultaneously in the same system.
|
|
|
|
For those descriptors that are common to both the 80286 and the 80386, the
|
|
presence of zeros in the final word causes the 80386 to interpret these
|
|
descriptors exactly as 80286 does; for example:
|
|
|
|
Base Address The high-order eight bits of the 32-bit base address are
|
|
zero, limiting base addresses to 24 bits.
|
|
|
|
Limit The high-order four bits of the limit field are zero,
|
|
restricting the value of the limit field to 64K.
|
|
|
|
Granularity bit The granularity bit is zero, which implies that the value
|
|
of the 16-bit limit is interpreted in units of one byte.
|
|
|
|
B-bit In a data-segment descriptor, the B-bit is zero, implying
|
|
that the segment is no larger than 64 Kbytes.
|
|
|
|
D-bit In an executable-segment descriptor, the D-bit is zero,
|
|
implying that 16-bit addressing and operands are the
|
|
default.
|
|
|
|
For formats of these descriptors and documentation of their use refer to
|
|
the iAPX 286 Programmer's Reference Manual.
|
|
|
|
|
|
13.2 Two ways to Execute 80286 Tasks
|
|
|
|
When porting 80286 programs to the 80386, there are two cases to consider:
|
|
|
|
1. Porting an entire 80286 system to the 80386, complete with 80286
|
|
operating system, loader, and system builder.
|
|
|
|
In this case, all tasks will have 80286 TSSs. The 80386 is being used
|
|
as a faster 286.
|
|
|
|
2. Porting selected 80286 applications to run in an 80386 environment
|
|
with an 80386 operating system, loader, and system builder.
|
|
|
|
In this case, the TSSs used to represent 80286 tasks should be
|
|
changed to 80386 TSSs. It is theoretically possible to mix 80286 and
|
|
80386 TSSs, but the benefits are slight and the problems are great. It
|
|
is recommended that all tasks in a 80386 software system have 80386
|
|
TSSs. It is not necessary to change the 80286 object modules
|
|
themselves; TSSs are usually constructed by the operating system, by
|
|
the loader, or by the system builder. Refer to Chapter 16 for further
|
|
discussion of the interface between 16-bit and 32-bit code.
|
|
|
|
|
|
13.3 Differences From 80286
|
|
|
|
The few differences that do exist primarily affect operating system code.
|
|
|
|
|
|
13.3.1 Wraparound of 80286 24-Bit Physical Address Space
|
|
|
|
With the 80286, any base and offset combination that addresses beyond 16M
|
|
bytes wraps around to the first megabyte of the 80286 address space. With
|
|
the 80386, since it has a greater physical address space, any such address
|
|
falls into the 17th megabyte. In the unlikely event that any software
|
|
depends on this anomaly, the same effect can be simulated on the 80386 by
|
|
using paging to map the first 64K bytes of the 17th megabyte of logical
|
|
addresses to physical addresses in the first megabyte.
|
|
|
|
|
|
13.3.2 Reserved Word of Descriptor
|
|
|
|
Because the 80386 uses the contents of the reserved word (last word) of
|
|
every descriptor, 80286 programs that place values in this word may not
|
|
execute correctly on the 80386.
|
|
|
|
|
|
13.3.3 New Descriptor Type Codes
|
|
|
|
Operating-system code that manages space in descriptor tables often uses an
|
|
invalid value in the access-rights field of descriptor-table entries to
|
|
identify unused entries. Access rights values of 80H and 00H remain invalid
|
|
for both the 80286 and 80386. Other values that were invalid on for the
|
|
80286 may be valid for the 80386 because of the additional descriptor types
|
|
defined by the 80386.
|
|
|
|
|
|
13.3.4 Restricted Semantics of LOCK
|
|
|
|
The 80286 processor implements the bus lock function differently than the
|
|
80386. Programs that use forms of memory locking specific to the 80286 may
|
|
not execute properly when transported to a specific application of the
|
|
80386.
|
|
|
|
The LOCK prefix and its corresponding output signal should only 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
|
|
other instruction.
|
|
|
|
þ Bit test and change: BTS, BTR, BTC.
|
|
þ Exchange: XCHG.
|
|
þ One-operand arithmetic and logical: INC, DEC, NOT, and NEG.
|
|
þ Two-operand arithmetic and logical: ADD, ADC, SUB, SBB, AND, OR, XOR.
|
|
|
|
A locked instruction is guaranteed to lock only the area of memory defined
|
|
by the destination operand, but may lock a larger memory area. For example,
|
|
typical 8086 and 80286 configurations lock the entire physical memory space.
|
|
With the 80386, the defined area of memory 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.
|
|
|
|
|
|
13.3.5 Additional Exceptions
|
|
|
|
The 80386 defines new exceptions that can occur even in systems designed
|
|
for the 80286.
|
|
|
|
þ Exception #6 ÄÄ invalid opcode
|
|
|
|
This exception can result from improper use of the LOCK instruction.
|
|
|
|
þ Exception #14 ÄÄ page fault
|
|
|
|
This exception may occur in an 80286 program if the operating system
|
|
enables paging. Paging can be used in a system with 80286 tasks as long
|
|
as all tasks use the same page directory. Because there is no place in
|
|
an 80286 TSS to store the PDBR, switching to an 80286 task does not
|
|
change the value of PDBR. Tasks ported from the 80286 should be given
|
|
80386 TSSs so they can take full advantage of paging.
|
|
|
|
|
|
Chapter 14 80386 Real-Address Mode
|
|
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
|
|
The real-address mode of the 80386 executes object code designed for
|
|
execution on 8086, 8088, 80186, or 80188 processors, or for execution in the
|
|
real-address mode of an 80286:
|
|
|
|
In effect, the architecture of the 80386 in this mode is almost identical
|
|
to that of the 8086, 8088, 80186, and 80188. To a programmer, an 80386 in
|
|
real-address mode appears as a high-speed 8086 with extensions to the
|
|
instruction set and registers. The principal features of this architecture
|
|
are defined in Chapters 2 and 3.
|
|
|
|
This chapter discusses certain additional topics that complete the system
|
|
programmer's view of the 80386 in real-address mode:
|
|
|
|
þ Address formation.
|
|
þ Extensions to registers and instructions.
|
|
þ Interrupt and exception handling.
|
|
þ Entering and leaving real-address mode.
|
|
þ Real-address-mode exceptions.
|
|
þ Differences from 8086.
|
|
þ Differences from 80286 real-address mode.
|
|
|
|
|
|
14.1 Physical Address Formation
|
|
|
|
The 80386 provides a one Mbyte + 64 Kbyte memory space for an 8086 program.
|
|
Segment relocation is performed as in the 8086: the 16-bit value in a
|
|
segment selector is shifted left by four bits to form the base address of a
|
|
segment. The effective address is extended with four high order zeros and
|
|
added to the base to form a linear address as Figure 14-1 illustrates. (The
|
|
linear address is equivalent to the physical address, because paging is not
|
|
used in real-address mode.) Unlike the 8086, the resulting linear address
|
|
may have up to 21 significant bits. There is a possibility of a carry when
|
|
the base address is added to the effective address. On the 8086, the carried
|
|
bit is truncated, whereas on the 80386 the carried bit is stored in bit
|
|
position 20 of the linear address.
|
|
|
|
Unlike the 8086 and 80286, 32-bit effective addresses can be generated (via
|
|
the address-size prefix); however, the value of a 32-bit address may not
|
|
exceed 65535 without causing an exception. For full compatibility with 80286
|
|
real-address mode, pseudo-protection faults (interrupt 12 or 13 with no
|
|
error code) occur if an effective address is generated outside the range 0
|
|
through 65535.
|
|
|
|
|
|
Figure 14-1. Real-Address Mode Address Formation
|
|
|
|
19 3 0
|
|
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍ»
|
|
BASE º 16-BIT SEGMENT SELECTOR ³ 0 0 0 0 º
|
|
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍͼ
|
|
|
|
+
|
|
19 15 0
|
|
ÉÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
|
OFFSET º 0 0 0 0 ³ 16-BIT EFFECTIVE ADDRESS º
|
|
ÈÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
|
|
|
=
|
|
20 0
|
|
LINEAR ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
|
ADDRESS º X X X X X X X X X X X X X X X X X X X X X X º
|
|
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
|
|
|
|
|
14.2 Registers and Instructions
|
|
|
|
The register set available in real-address mode includes all the registers
|
|
defined for the 8086 plus the new registers introduced by the 80386: FS, GS,
|
|
debug registers, control registers, and test registers. New instructions
|
|
that explicitly operate on the segment registers FS and GS are available,
|
|
and the new segment-override prefixes can be used to cause instructions to
|
|
utilize FS and GS for address calculations. Instructions can utilize 32-bit
|
|
operands through the use of the operand size prefix.
|
|
|
|
The instruction codes that cause undefined opcode traps (interrupt 6)
|
|
include instructions of the protected mode that manipulate or interrogate
|
|
80386 selectors and descriptors; namely, VERR, VERW, LAR, LSL, LTR, STR,
|
|
LLDT, and SLDT. Programs executing in real-address mode are able to take
|
|
advantage of the new applications-oriented instructions added to the
|
|
architecture by the introduction of the 80186/80188, 80286 and 80386:
|
|
|
|
þ New instructions introduced by 80186/80188 and 80286.
|
|
|
|
ÄÄ PUSH immediate data
|
|
ÄÄ Push all and pop all (PUSHA and POPA)
|
|
ÄÄ Multiply immediate data
|
|
ÄÄ Shift and rotate by immediate count
|
|
ÄÄ String I/O
|
|
ÄÄ ENTER and LEAVE
|
|
ÄÄ BOUND
|
|
|
|
þ New instructions introduced by 80386.
|
|
|
|
ÄÄ LSS, LFS, LGS instructions
|
|
ÄÄ Long-displacement conditional jumps
|
|
ÄÄ Single-bit instructions
|
|
ÄÄ Bit scan
|
|
ÄÄ Double-shift instructions
|
|
ÄÄ Byte set on condition
|
|
ÄÄ Move with sign/zero extension
|
|
ÄÄ Generalized multiply
|
|
ÄÄ MOV to and from control registers
|
|
ÄÄ MOV to and from test registers
|
|
ÄÄ MOV to and from debug registers
|
|
|
|
|
|
14.3 Interrupt and Exception Handling
|
|
|
|
Interrupts and exceptions in 80386 real-address mode work as much as they
|
|
do on an 8086. Interrupts and exceptions vector to interrupt procedures via
|
|
an interrupt table. The processor multiplies the interrupt or exception
|
|
identifier by four to obtain an index into the interrupt table. The entries
|
|
of the interrupt table are far pointers to the entry points of interrupt or
|
|
exception handler procedures. When an interrupt occurs, the processor
|
|
pushes the current values of CS:IP onto the stack, disables interrupts,
|
|
clears TF (the single-step flag), then transfers control to the location
|
|
specified in the interrupt table. An IRET instruction at the end of the
|
|
handler procedure reverses these steps before returning control to the
|
|
interrupted procedure.
|
|
|
|
The primary difference in the interrupt handling of the 80386 compared to
|
|
the 8086 is that the location and size of the interrupt table depend on the
|
|
contents of the IDTR (IDT register). Ordinarily, this fact is not apparent
|
|
to programmers, because, after RESET, the IDTR contains a base address of 0
|
|
and a limit of 3FFH, which is compatible with the 8086. However, the LIDT
|
|
instruction can be used in real-address mode to change the base and limit
|
|
values in the IDTR. Refer to Chapter 9 for details on the IDTR, and the
|
|
LIDT and SIDT instructions. If an interrupt occurs and the corresponding
|
|
entry of the interrupt table is beyond the limit stored in the IDTR, the
|
|
processor raises exception 8.
|
|
|
|
|
|
14.4 Entering and Leaving Real-Address Mode
|
|
|
|
Real-address mode is in effect after a signal on the RESET pin. Even if the
|
|
system is going to be used in protected mode, the start-up program will
|
|
execute in real-address mode temporarily while initializing for protected
|
|
mode.
|
|
|
|
|
|
14.4.1 Switching to Protected Mode
|
|
|
|
The only way to leave real-address mode is to switch to protected mode. The
|
|
processor enters protected mode when a MOV to CR0 instruction sets the PE
|
|
(protection enable) bit in CR0. (For compatibility with the 80286, the LMSW
|
|
instruction may also be used to set the PE bit.)
|
|
|
|
Refer to Chapter 10 "Initialization" for other aspects of switching to
|
|
protected mode.
|
|
|
|
|
|
14.5 Switching Back to Real-Address Mode
|
|
|
|
The processor reenters real-address mode if software clears the PE bit in
|
|
CR0 with a MOV to CR0 instruction. A procedure that attempts to do this,
|
|
however, should proceed as follows:
|
|
|
|
1. If paging is enabled, perform the following sequence:
|
|
|
|
þ Transfer control to linear addresses that have an identity mapping;
|
|
i.e., linear addresses equal physical addresses.
|
|
|
|
þ Clear the PG bit in CR0.
|
|
|
|
þ Move zeros to CR3 to clear out the paging cache.
|
|
|
|
2. Transfer control to a segment that has a limit of 64K (FFFFH). This
|
|
loads the CS register with the limit it needs to have in real mode.
|
|
|
|
3. Load segment registers SS, DS, ES, FS, and GS with a selector that
|
|
points to a descriptor containing the following values, which are
|
|
appropriate to real mode:
|
|
|
|
þ Limit = 64K (FFFFH)
|
|
þ Byte granular (G = 0)
|
|
þ Expand up (E = 0)
|
|
þ Writable (W = 1)
|
|
þ Present (P = 1)
|
|
þ Base = any value
|
|
|
|
4. Disable interrupts. A CLI instruction disables INTR interrupts. NMIs
|
|
can be disabled with external circuitry.
|
|
|
|
5. Clear the PE bit.
|
|
|
|
6. Jump to the real mode code to be executed using a far JMP. This
|
|
action flushes the instruction queue and puts appropriate values in
|
|
the access rights of the CS register.
|
|
|
|
7. Use the LIDT instruction to load the base and limit of the real-mode
|
|
interrupt vector table.
|
|
|
|
8. Enable interrupts.
|
|
|
|
9. Load the segment registers as needed by the real-mode code.
|
|
|
|
|
|
14.6 Real-Address Mode Exceptions
|
|
|
|
The 80386 reports some exceptions differently when executing in
|
|
real-address mode than when executing in protected mode. Table 14-1 details
|
|
the real-address-mode exceptions.
|
|
|
|
|
|
14.7 Differences From 8086
|
|
|
|
In general, the 80386 in real-address mode will correctly execute ROM-based
|
|
software designed for the 8086, 8088, 80186, and 80188. Following is a list
|
|
of the minor differences between 8086 execution on the 80386 and on an 8086.
|
|
|
|
1. Instruction clock counts.
|
|
|
|
The 80386 takes fewer clocks for most instructions than the 8086/8088.
|
|
The areas most likely to be affected are:
|
|
|
|
þ Delays required by I/O devices between I/O operations.
|
|
|
|
þ Assumed delays with 8086/8088 operating in parallel with an 8087.
|
|
|
|
2. Divide Exceptions Point to the DIV instruction.
|
|
|
|
Divide exceptions on the 80386 always leave the saved CS:IP value
|
|
pointing to the instruction that failed. On the 8086/8088, the CS:IP
|
|
value points to the next instruction.
|
|
|
|
3. Undefined 8086/8088 opcodes.
|
|
|
|
Opcodes that were not defined for the 8086/8088 will cause exception
|
|
6 or will execute one of the new instructions defined for the 80386.
|
|
|
|
4. Value written by PUSH SP.
|
|
|
|
The 80386 pushes a different value on the stack for PUSH SP than the
|
|
8086/8088. The 80386 pushes the value of SP before SP is incremented
|
|
as part of the push operation; the 8086/8088 pushes the value of SP
|
|
after it is incremented. If the value pushed is important, replace
|
|
PUSH SP instructions with the following three instructions:
|
|
|
|
PUSH BP
|
|
MOV BP, SP
|
|
XCHG BP, [BP]
|
|
|
|
This code functions as the 8086/8088 PUSH SP instruction on the 80386.
|
|
|
|
5. Shift or rotate by more than 31 bits.
|
|
|
|
The 80386 masks all shift and rotate counts to the low-order five
|
|
bits. This MOD 32 operation limits the count to a maximum of 31 bits,
|
|
thereby limiting the time that interrupt response is delayed while
|
|
the instruction is executing.
|
|
|
|
6. Redundant prefixes.
|
|
|
|
The 80386 sets a limit of 15 bytes on instruction length. The only
|
|
way to violate this limit is by putting redundant prefixes before an
|
|
instruction. Exception 13 occurs if the limit on instruction length
|
|
is violated. The 8086/8088 has no instruction length limit.
|
|
|
|
7. Operand crossing offset 0 or 65,535.
|
|
|
|
On the 8086, an attempt to access a memory operand that crosses
|
|
offset 65,535 (e.g., MOV a word to offset 65,535) or offset 0 (e.g.,
|
|
PUSH a word when SP = 1) causes the offset to wrap around modulo
|
|
65,536. The 80386 raises an exception in these casesÄÄexception 13 if
|
|
the segment is a data segment (i.e., if CS, DS, ES, FS, or GS is being
|
|
used to address the segment), exception 12 if the segment is a stack
|
|
segment (i.e., if SS is being used).
|
|
|
|
8. Sequential execution across offset 65,535.
|
|
|
|
On the 8086, if sequential execution of instructions proceeds past
|
|
offset 65,535, the processor fetches the next instruction byte from
|
|
offset 0 of the same segment. On the 80386, the processor raises
|
|
exception 13 in such a case.
|
|
|
|
9. LOCK is restricted to certain instructions.
|
|
|
|
The LOCK prefix and its corresponding output signal should only be
|
|
used to prevent other bus masters from interrupting a data movement
|
|
operation. The 80386 always asserts the LOCK signal during an XCHG
|
|
instruction with memory (even if the LOCK prefix is not used). LOCK
|
|
may only be used with the following 80386 instructions when they
|
|
update memory: BTS, BTR, BTC, XCHG, ADD, ADC, SUB, SBB, INC, DEC,
|
|
AND, OR, XOR, NOT, and NEG. An undefined-opcode exception
|
|
(interrupt 6) results from using LOCK before any other instruction.
|
|
|
|
10. Single-stepping external interrupt handlers.
|
|
|
|
The priority of the 80386 single-step exception is different from that
|
|
of the 8086/8088. The change prevents an external interrupt handler
|
|
from being single-stepped if the interrupt occurs while a program is
|
|
being single-stepped. The 80386 single-step exception has higher
|
|
priority that any external interrupt. The 80386 will still single-step
|
|
through an interrupt handler invoked by the INT instructions or by an
|
|
exception.
|
|
|
|
11. IDIV exceptions for quotients of 80H or 8000H.
|
|
|
|
The 80386 can generate the largest negative number as a quotient for
|
|
the IDIV instruction. The 8086/8088 causes exception zero instead.
|
|
|
|
12. Flags in stack.
|
|
|
|
The setting of the flags stored by PUSHF, by interrupts, and by
|
|
exceptions is different from that stored by the 8086 in bit positions
|
|
12 through 15. On the 8086 these bits are stored as ones, but in
|
|
80386 real-address mode bit 15 is always zero, and bits 14 through 12
|
|
reflect the last value loaded into them.
|
|
|
|
13. NMI interrupting NMI handlers.
|
|
|
|
After an NMI is recognized on the 80386, the NMI interrupt is masked
|
|
until an IRET instruction is executed.
|
|
|
|
14. Coprocessor errors vector to interrupt 16.
|
|
|
|
Any 80386 system with a coprocessor must use interrupt vector 16 for
|
|
the coprocessor error exception. If an 8086/8088 system uses another
|
|
vector for the 8087 interrupt, both vectors should point to the
|
|
coprocessor-error exception handler.
|
|
|
|
15. Numeric exception handlers should allow prefixes.
|
|
|
|
On the 80386, the value of CS:IP saved for coprocessor exceptions
|
|
points at any prefixes before an ESC instruction. On 8086/8088
|
|
systems, the saved CS:IP points to the ESC instruction.
|
|
|
|
16. Coprocessor does not use interrupt controller.
|
|
|
|
The coprocessor error signal to the 80386 does not pass through an
|
|
interrupt controller (an 8087 INT signal does). Some instructions in
|
|
a coprocessor error handler may need to be deleted if they deal with
|
|
the interrupt controller.
|
|
|
|
17. Six new interrupt vectors.
|
|
|
|
The 80386 adds six exceptions that arise only if the 8086 program has
|
|
a hidden bug. It is recommended that exception handlers be added that
|
|
treat these exceptions as invalid operations. This additional
|
|
software does not significantly affect the existing 8086 software
|
|
because the interrupts do not normally occur. These interrupt
|
|
identifiers should not already have been used by the 8086 software,
|
|
because they are in the range reserved by Intel. Table 14-2 describes
|
|
the new 80386 exceptions.
|
|
|
|
18. One megabyte wraparound.
|
|
|
|
The 80386 does not wrap addresses at 1 megabyte in real-address mode.
|
|
On members of the 8086 family, it possible to specify addresses
|
|
greater than one megabyte. For example, with a selector value 0FFFFH
|
|
and an offset of 0FFFFH, the effective address would be 10FFEFH (1
|
|
Mbyte + 65519). The 8086, which can form adresses only up to 20 bits
|
|
long, truncates the high-order bit, thereby "wrapping" this address
|
|
to 0FFEFH. However, the 80386, which can form addresses up to 32
|
|
bits long does not truncate such an address.
|
|
|
|
|
|
Table 14-1. 80386 Real-Address Mode Exceptions
|
|
|
|
|
|
Description Interrupt Function that Can Return Address
|
|
Number Generate the Exception Points to Faulting
|
|
Instruction
|
|
Divide error 0 DIV, IDIV YES
|
|
Debug exceptions 1 All
|
|
Some debug exceptions point to the faulting instruction, others to the
|
|
next instruction. The exception handler can determine which has occurred by
|
|
examining DR6.
|
|
|
|
|
|
|
|
|
|
|
|
Breakpoint 3 INT NO
|
|
Overflow 4 INTO NO
|
|
Bounds check 5 BOUND YES
|
|
Invalid opcode 6 Any undefined opcode or LOCK YES
|
|
used with wrong instruction
|
|
Coprocessor not available 7 ESC or WAIT YES
|
|
Interrupt table limit too small 8 INT vector is not within IDTR YES
|
|
limit
|
|
Reserved 9-12
|
|
Stack fault 12 Memory operand crosses offset YES
|
|
0 or 0FFFFH
|
|
Pseudo-protection exception 13 Memory operand crosses offset YES
|
|
0FFFFH or attempt to execute
|
|
past offset 0FFFFH or
|
|
instruction longer than 15
|
|
bytes
|
|
Reserved 14,15
|
|
Coprocessor error 16 ESC or WAIT YES
|
|
Coprocessor errors are reported on the first ESC or WAIT instruction
|
|
after the ESC instruction that caused the error.
|
|
|
|
|
|
|
|
|
|
|
|
Two-byte SW interrupt 0-255 INT n NO
|
|
|
|
|
|
Table 14-2. New 80386 Exceptions
|
|
|
|
Interrupt Function
|
|
Identifier
|
|
|
|
5 A BOUND instruction was executed with a register value outside
|
|
the limit values.
|
|
|
|
6 An undefined opcode was encountered or LOCK was used improperly
|
|
before an instruction to which it does not apply.
|
|
|
|
7 The EM bit in the MSW is set when an ESC instruction was
|
|
encountered. This exception also occurs on a WAIT instruction
|
|
if TS is set.
|
|
|
|
8 An exception or interrupt has vectored to an interrupt table
|
|
entry beyond the interrupt table limit in IDTR. This can occur
|
|
only if the LIDT instruction has changed the limit from the
|
|
default value of 3FFH, which is enough for all 256 interrupt
|
|
IDs.
|
|
|
|
12 Operand crosses extremes of stack segment, e.g., MOV operation
|
|
at offset 0FFFFH or push with SP=1 during PUSH, CALL, or INT.
|
|
|
|
13 Operand crosses extremes of a segment other than a stack
|
|
segment; or sequential instruction execution attempts to
|
|
proceed beyond offset 0FFFFH; or an instruction is longer than
|
|
15 bytes (including prefixes).
|
|
|
|
|
|
14.8 Differences From 80286 Real-Address Mode
|
|
|
|
The few differences that exist between 80386 real-address mode and 80286
|
|
real-address mode are not likely to affect any existing 80286 programs
|
|
except possibly the system initialization procedures.
|
|
|
|
|
|
14.8.1 Bus Lock
|
|
|
|
The 80286 processor implements the bus lock function differently than the
|
|
80386. Programs that use forms of memory locking specific to the 80286 may
|
|
not execute properly if transported to a specific application of the 80386.
|
|
|
|
The LOCK prefix and its corresponding output signal should only 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
|
|
other instruction.
|
|
|
|
þ Bit test and change: BTS, BTR, BTC.
|
|
þ Exchange: XCHG.
|
|
þ One-operand arithmetic and logical: INC, DEC, NOT, and NEG.
|
|
þ Two-operand arithmetic and logical: ADD, ADC, SUB, SBB, AND, OR, XOR.
|
|
|
|
A locked instruction is guaranteed to lock only the area of memory defined
|
|
by the destination operand, but may lock a larger memory area. For example,
|
|
typical 8086 and 80286 configurations lock the entire physical memory space.
|
|
With the 80386, the defined area of memory is guranteed 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.
|
|
|
|
|
|
14.8.2 Location of First Instruction
|
|
|
|
The starting location is 0FFFFFFF0H (sixteen bytes from end of 32-bit
|
|
address space) on the 80386 rather than 0FFFFF0H (sixteen bytes from end of
|
|
24-bit address space) as on the 80286. Many 80286 ROM initialization
|
|
programs will work correctly in this new environment. Others can be made to
|
|
work correctly with external hardware that redefines the signals on
|
|
A{31-20}.
|
|
|
|
|
|
14.8.3 Initial Values of General Registers
|
|
|
|
On the 80386, certain general registers may contain different values after
|
|
RESET than on the 80286. This should not cause compatibility problems,
|
|
because the content of 8086 registers after RESET is undefined. If
|
|
self-test is requested during the reset sequence and errors are detected in
|
|
the 80386 unit, EAX will contain a nonzero value. EDX contains the component
|
|
and revision identifier. Refer to Chapter 10 for more information.
|
|
|
|
|
|
14.8.4 MSW Initialization
|
|
|
|
The 80286 initializes the MSW register to FFF0H, but the 80386 initializes
|
|
this register to 0000H. This difference should have no effect, because the
|
|
bits that are different are undefined on the 80286. Programs that read the
|
|
value of the MSW will behave differently on the 80386 only if they depend on
|
|
the setting of the undefined, high-order bits.
|
|
|
|
|
|
Chapter 15 Virtual 8086 Mode
|
|
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
|
|
The 80386 supports execution of one or more 8086, 8088, 80186, or 80188
|
|
programs in an 80386 protected-mode environment. An 8086 program runs in
|
|
this environment as part of a V86 (virtual 8086) task. V86 tasks take
|
|
advantage of the hardware support of multitasking offered by the protected
|
|
mode. Not only can there be multiple V86 tasks, each one executing an 8086
|
|
program, but V86 tasks can be multiprogrammed with other 80386 tasks.
|
|
|
|
The purpose of a V86 task is to form a "virtual machine" with which to
|
|
execute an 8086 program. A complete virtual machine consists not only of
|
|
80386 hardware but also of systems software. Thus, the emulation of an 8086
|
|
is the result of cooperation between hardware and software:
|
|
|
|
þ The hardware provides a virtual set of registers (via the TSS), a
|
|
virtual memory space (the first megabyte of the linear address space of
|
|
the task), and directly executes all instructions that deal with these
|
|
registers and with this address space.
|
|
|
|
þ The software controls the external interfaces of the virtual machine
|
|
(I/O, interrupts, and exceptions) in a manner consistent with the
|
|
larger environment in which it executes. In the case of I/O, software
|
|
can choose either to emulate I/O instructions or to let the hardware
|
|
execute them directly without software intervention.
|
|
|
|
Software that helps implement virtual 8086 machines is called a V86
|
|
monitor.
|
|
|
|
|
|
15.1 Executing 8086 Code
|
|
|
|
The processor executes in V86 mode when the VM (virtual machine) bit in the
|
|
EFLAGS register is set. The processor tests this flag under two general
|
|
conditions:
|
|
|
|
1. When loading segment registers to know whether to use 8086-style
|
|
address formation.
|
|
|
|
2. When decoding instructions to determine which instructions are
|
|
sensitive to IOPL.
|
|
|
|
Except for these two modifications to its normal operations, the 80386 in
|
|
V86 mode operated much as in protected mode.
|
|
|
|
|
|
15.1.1 Registers and Instructions
|
|
|
|
The register set available in V86 mode includes all the registers defined
|
|
for the 8086 plus the new registers introduced by the 80386: FS, GS, debug
|
|
registers, control registers, and test registers. New instructions that
|
|
explicitly operate on the segment registers FS and GS are available, and the
|
|
new segment-override prefixes can be used to cause instructions to utilize
|
|
FS and GS for address calculations. Instructions can utilize 32-bit
|
|
operands through the use of the operand size prefix.
|
|
|
|
8086 programs running as V86 tasks are able to take advantage of the new
|
|
applications-oriented instructions added to the architecture by the
|
|
introduction of the 80186/80188, 80286 and 80386:
|
|
|
|
þ New instructions introduced by 80186/80188 and 80286.
|
|
ÄÄ PUSH immediate data
|
|
ÄÄ Push all and pop all (PUSHA and POPA)
|
|
ÄÄ Multiply immediate data
|
|
ÄÄ Shift and rotate by immediate count
|
|
ÄÄ String I/O
|
|
ÄÄ ENTER and LEAVE
|
|
ÄÄ BOUND
|
|
|
|
þ New instructions introduced by 80386.
|
|
ÄÄ LSS, LFS, LGS instructions
|
|
ÄÄ Long-displacement conditional jumps
|
|
ÄÄ Single-bit instructions
|
|
ÄÄ Bit scan
|
|
ÄÄ Double-shift instructions
|
|
ÄÄ Byte set on condition
|
|
ÄÄ Move with sign/zero extension
|
|
ÄÄ Generalized multiply
|
|
|
|
|
|
15.1.2 Linear Address Formation
|
|
|
|
In V86 mode, the 80386 processor does not interpret 8086 selectors by
|
|
referring to descriptors; instead, it forms linear addresses as an 8086
|
|
would. It shifts the selector left by four bits to form a 20-bit base
|
|
address. The effective address is extended with four high-order zeros and
|
|
added to the base address to create a linear address as Figure 15-1
|
|
illustrates.
|
|
|
|
Because of the possibility of a carry, the resulting linear address may
|
|
contain up to 21 significant bits. An 8086 program may generate linear
|
|
addresses anywhere in the range 0 to 10FFEFH (one megabyte plus
|
|
approximately 64 Kbytes) of the task's linear address space.
|
|
|
|
V86 tasks generate 32-bit linear addresses. While an 8086 program can only
|
|
utilize the low-order 21 bits of a linear address, the linear address can be
|
|
mapped via page tables to any 32-bit physical address.
|
|
|
|
Unlike the 8086 and 80286, 32-bit effective addresses can be generated (via
|
|
the address-size prefix); however, the value of a 32-bit address may not
|
|
exceed 65,535 without causing an exception. For full compatibility with
|
|
80286 real-address mode, pseudo-protection faults (interrupt 12 or 13 with
|
|
no error code) occur if an address is generated outside the range 0 through
|
|
65,535.
|
|
|
|
|
|
Figure 15-1. V86 Mode Address Formation
|
|
|
|
19 3 0
|
|
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍ»
|
|
BASE º 16-BIT SEGMENT SELECTOR ³ 0 0 0 0 º
|
|
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍͼ
|
|
|
|
+
|
|
19 15 0
|
|
ÉÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
|
OFFSET º 0 0 0 0 ³ 16-BIT EFFECTIVE ADDRESS º
|
|
ÈÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
|
|
|
=
|
|
20 0
|
|
LINEAR ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
|
ADDRESS º X X X X X X X X X X X X X X X X X X X X X X º
|
|
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
|
|
|
|
|
15.2 Structure of a V86 Task
|
|
|
|
A V86 task consists partly of the 8086 program to be executed and partly of
|
|
80386 "native mode" code that serves as the virtual-machine monitor. The
|
|
task must be represented by an 80386 TSS (not an 80286 TSS). The processor
|
|
enters V86 mode to execute the 8086 program and returns to protected mode to
|
|
execute the monitor or other 80386 tasks.
|
|
|
|
To run successfully in V86 mode, an existing 8086 program needs the
|
|
following:
|
|
|
|
þ A V86 monitor.
|
|
þ Operating-system services.
|
|
|
|
The V86 monitor is 80386 protected-mode code that executes at
|
|
privilege-level zero. The monitor consists primarily of initialization and
|
|
exception-handling procedures. As for any other 80386 program,
|
|
executable-segment descriptors for the monitor must exist in the GDT or in
|
|
the task's LDT. The linear addresses above 10FFEFH are available for the
|
|
V86 monitor, the operating system, and other systems software. The monitor
|
|
may also need data-segment descriptors so that it can examine the interrupt
|
|
vector table or other parts of the 8086 program in the first megabyte of the
|
|
address space.
|
|
|
|
In general, there are two options for implementing the 8086 operating
|
|
system:
|
|
|
|
1. The 8086 operating system may run as part of the 8086 code. This
|
|
approach is desirable for any of the following reasons:
|
|
|
|
þ The 8086 applications code modifies the operating system.
|
|
|
|
þ There is not sufficient development time to reimplement the 8086
|
|
operating system as 80386 code.
|
|
|
|
2. The 8086 operating system may be implemented or emulated in the V86
|
|
monitor. This approach is desirable for any of the following reasons:
|
|
|
|
þ Operating system functions can be more easily coordinated among
|
|
several V86 tasks.
|
|
|
|
þ The functions of the 8086 operating system can be easily emulated
|
|
by calls to the 80386 operating system.
|
|
|
|
Note that, regardless of the approach chosen for implementing the 8086
|
|
operating system, different V86 tasks may use different 8086 operating
|
|
systems.
|
|
|
|
|
|
15.2.1 Using Paging for V86 Tasks
|
|
|
|
Paging is not necessary for a single V86 task, but paging is useful or
|
|
necessary for any of the following reasons:
|
|
|
|
þ To create multiple V86 tasks. Each task must map the lower megabyte of
|
|
linear addresses to different physical locations.
|
|
|
|
þ To emulate the megabyte wrap. On members of the 8086 family, it is
|
|
possible to specify addresses larger than one megabyte. For example,
|
|
with a selector value of 0FFFFH and an offset of 0FFFFH, the effective
|
|
address would be 10FFEFH (one megabyte + 65519). The 8086, which can
|
|
form addresses only up to 20 bits long, truncates the high-order bit,
|
|
thereby "wrapping" this address to 0FFEFH. The 80386, however, which
|
|
can form addresses up to 32 bits long does not truncate such an
|
|
address. If any 8086 programs depend on this addressing anomaly, the
|
|
same effect can be achieved in a V86 task by mapping linear addresses
|
|
between 100000H and 110000H and linear addresses between 0 and 10000H
|
|
to the same physical addresses.
|
|
|
|
þ To create a virtual address space larger than the physical address
|
|
space.
|
|
|
|
þ To share 8086 OS code or ROM code that is common to several 8086
|
|
programs that are executing simultaneously.
|
|
|
|
þ To redirect or trap references to memory-mapped I/O devices.
|
|
|
|
|
|
15.2.2 Protection within a V86 Task
|
|
|
|
Because it does not refer to descriptors while executing 8086 programs, the
|
|
processor also does not utilize the protection mechanisms offered by
|
|
descriptors. To protect the systems software that runs in a V86 task from
|
|
the 8086 program, software designers may follow either of these approaches:
|
|
|
|
þ Reserve the first megabyte (plus 64 kilobytes) of each task's linear
|
|
address space for the 8086 program. An 8086 task cannot generate
|
|
addresses outside this range.
|
|
|
|
þ Use the U/S bit of page-table entries to protect the virtual-machine
|
|
monitor and other systems software in each virtual 8086 task's space.
|
|
When the processor is in V86 mode, CPL is 3. Therefore, an 8086 program
|
|
has only user privileges. If the pages of the virtual-machine monitor
|
|
have supervisor privilege, they cannot be accessed by the 8086 program.
|
|
|
|
|
|
15.3 Entering and Leaving V86 Mode
|
|
|
|
Figure 15-2 summarizes the ways that the processor can enter and leave an
|
|
8086 program. The processor can enter V86 by either of two means:
|
|
|
|
1. A task switch to an 80386 task loads the image of EFLAGS from the new
|
|
TSS. The TSS of the new task must be an 80386 TSS, not an 80286 TSS,
|
|
because the 80286 TSS does not store the high-order word of EFLAGS,
|
|
which contains the VM flag. A value of one in the VM bit of the new
|
|
EFLAGS indicates that the new task is executing 8086 instructions;
|
|
therefore, while loading the segment registers from the TSS, the
|
|
processor forms base addresses as the 8086 would.
|
|
|
|
2. An IRET from a procedure of an 80386 task loads the image of EFLAGS
|
|
from the stack. A value of one in VM in this case indicates that the
|
|
procedure to which control is being returned is an 8086 procedure. The
|
|
CPL at the time the IRET is executed must be zero, else the processor
|
|
does not change VM.
|
|
|
|
The processor leaves V86 mode when an interrupt or exception occurs. There
|
|
are two cases:
|
|
|
|
1. The interrupt or exception causes a task switch. A task switch from a
|
|
V86 task to any other task loads EFLAGS from the TSS of the new task.
|
|
If the new TSS is an 80386 TSS and the VM bit in the EFLAGS image is
|
|
zero or if the new TSS is an 80286 TSS, then the processor clears the
|
|
VM bit of EFLAGS, loads the segment registers from the new TSS using
|
|
80386-style address formation, and begins executing the instructions
|
|
of the new task according to 80386 protected-mode semantics.
|
|
|
|
2. The interrupt or exception vectors to a privilege-level zero
|
|
procedure. The processor stores the current setting of EFLAGS on the
|
|
stack, then clears the VM bit. The interrupt or exception handler,
|
|
therefore, executes as "native" 80386 protected-mode code. If an
|
|
interrupt or exception vectors to a conforming segment or to a
|
|
privilege level other than three, the processor causes a
|
|
general-protection exception; the error code is the selector of the
|
|
executable segment to which transfer was attempted.
|
|
|
|
Systems software does not manipulate the VM flag directly, but rather
|
|
manipulates the image of the EFLAGS register that is stored on the stack or
|
|
in the TSS. The V86 monitor sets the VM flag in the EFLAGS image on the
|
|
stack or in the TSS when first creating a V86 task. Exception and interrupt
|
|
handlers can examine the VM flag on the stack. If the interrupted procedure
|
|
was executing in V86 mode, the handler may need to invoke the V86 monitor.
|
|
|
|
|
|
Figure 15-2. Entering and Leaving the 8086 Program
|
|
|
|
MODE TRANSITION DIAGRAM
|
|
|
|
ÉÍÍÍÍÍÍÍÍÍÍÍ»
|
|
TASK SWITCH º INITIAL º
|
|
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ ENTRY º
|
|
³ OR IRET ÈÍÍÍÍÍÍÍÍÍÍͼ
|
|
³
|
|
|
|
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» INTERRUPT, EXCEPTION ÉÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
|
º 8086 PROGRAM ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĺ V86 MONITOR º
|
|
º (V86 MODE) ºÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ (PROTECTED º
|
|
ÈÍÍÍÍÍÍÍÑÍÍÍÍÍͼ IRET º MODE) º
|
|
³ ÈÍÍÍÍÍÑÍÍÍÍÍÍͼ
|
|
³ ³ ³
|
|
³ ³ ³ ³
|
|
³ ³ ³ ³
|
|
³ ³TASK SWITCH ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» TASK SWITCH ³
|
|
³ ÀÄÄÄÄÄÄÄÄÄÄĺ OTHER 80386 TASKS ºÄÄÄÄÄÄÄÄÄÙ ³
|
|
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄĶ (PROTECTED MODE) ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
|
TASK SWITCH ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ TASK SWITCH
|
|
|
|
|
|
15.3.1 Transitions Through Task Switches
|
|
|
|
A task switch to or from a V86 task may be due to any of three causes:
|
|
|
|
1. An interrupt that vectors to a task gate.
|
|
2. An action of the scheduler of the 80386 operating system.
|
|
3. An IRET when the NT flag is set.
|
|
|
|
In any of these cases, the processor changes the VM bit in EFLAGS according
|
|
to the image of EFLAGS in the new TSS. If the new TSS is an 80286 TSS, the
|
|
high-order word of EFLAGS is not in the TSS; the processor clears VM in this
|
|
case. The processor updates VM prior to loading the segment registers from
|
|
the images in the new TSS. The new setting of VM determines whether the
|
|
processor interprets the new segment-register images as 8086 selectors or
|
|
80386/80286 selectors.
|
|
|
|
|
|
15.3.2 Transitions Through Trap Gates and Interrupt Gates
|
|
|
|
The processor leaves V86 mode as the result of an exception or interrupt
|
|
that vectors via a trap or interrupt gate to a privilege-level zero
|
|
procedure. The exception or interrupt handler returns to the 8086 code by
|
|
executing an IRET.
|
|
|
|
Because it was designed for execution by an 8086 processor, an 8086 program
|
|
in a V86 task will have an 8086-style interrupt table starting at linear
|
|
address zero. However, the 80386 does not use this table directly. For all
|
|
exceptions and interrupts that occur in V86 mode, the processor vectors
|
|
through the IDT. The IDT entry for an interrupt or exception that occurs in
|
|
a V86 task must contain either:
|
|
|
|
þ A task gate.
|
|
|
|
þ An 80386 trap gate (type 14) or an 80386 interrupt gate (type 15),
|
|
which must point to a nonconforming, privilege-level zero, code
|
|
segment.
|
|
|
|
Interrupts and exceptions that have 80386 trap or interrupt gates in the
|
|
IDT vector to the appropriate handler procedure at privilege-level zero. The
|
|
contents of all the 8086 segment registers are stored on the PL 0 stack.
|
|
Figure 15-3 shows the format of the PL 0 stack after an exception or
|
|
interrupt that occurs while a V86 task is executing an 8086 program.
|
|
|
|
After the processor stores all the 8086 segment registers on the PL 0
|
|
stack, it loads all the segment registers with zeros before starting to
|
|
execute the handler procedure. This permits the interrupt handler to safely
|
|
save and restore the DS, ES, FS, and GS registers as 80386 selectors.
|
|
Interrupt handlers that may be invoked in the context of either a regular
|
|
task or a V86 task, can use the same prolog and epilog code for register
|
|
saving regardless of the kind of task. Restoring zeros to these registers
|
|
before execution of the IRET does not cause a trap in the interrupt handler.
|
|
Interrupt procedures that expect values in the segment registers or that
|
|
return values via segment registers have to use the register images stored
|
|
on the PL 0 stack. Interrupt handlers that need to know whether the
|
|
interrupt occurred in V86 mode can examine the VM bit in the stored EFLAGS
|
|
image.
|
|
|
|
An interrupt handler passes control to the V86 monitor if the VM bit is set
|
|
in the EFLAGS image stored on the stack and the interrupt or exception is
|
|
one that the monitor needs to handle. The V86 monitor may either:
|
|
|
|
þ Handle the interrupt completely within the V86 monitor.
|
|
þ Invoke the 8086 program's interrupt handler.
|
|
|
|
Reflecting an interrupt or exception back to the 8086 code involves the
|
|
following steps:
|
|
|
|
1. Refer to the 8086 interrupt vector to locate the appropriate handler
|
|
procedure.
|
|
|
|
2. Store the state of the 8086 program on the privilege-level three
|
|
stack.
|
|
|
|
3. Change the return link on the privilege-level zero stack to point to
|
|
the privilege-level three handler procedure.
|
|
|
|
4. Execute an IRET so as to pass control to the handler.
|
|
|
|
5. When the IRET by the privilege-level three handler again traps to the
|
|
V86 monitor, restore the return link on the privilege-level zero stack
|
|
to point to the originally interrupted, privilege-level three
|
|
procedure.
|
|
|
|
6. Execute an IRET so as to pass control back to the interrupted
|
|
procedure.
|
|
|
|
|
|
Figure 15-3. PL 0 Stack after Interrupt in V86 Task
|
|
|
|
|
|
WITHOUT ERROR CODE WITH ERROR CODE
|
|
31 0 31 0
|
|
ÉÍÍÍÍÍÍËÍÍÍÍÍÍÍ»ÄÄÄÄ¿ ÉÍÍÍÍÍÍËÍÍÍÍÍÍÍ»ÄÄÄÄ¿
|
|
º±±±±±±ºOLD GS º ³ º±±±±±±ºOLD GS º ³
|
|
ÌÍÍÍÍÍÍÎÍÍÍÍÍÍ͹ SS:ESP ÌÍÍÍÍÍÍÎÍÍÍÍÍÍ͹ SS:ESP
|
|
D O º±±±±±±ºOLD FS º FROM TSS º±±±±±±ºOLD FS º FROM TSS
|
|
I F ÌÍÍÍÍÍÍÎÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÎÍÍÍÍÍÍ͹
|
|
R º±±±±±±ºOLD DS º º±±±±±±ºOLD DS º
|
|
E E ÌÍÍÍÍÍÍÎÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÎÍÍÍÍÍÍ͹
|
|
C X º±±±±±±ºOLD ES º º±±±±±±ºOLD ES º
|
|
T P ÌÍÍÍÍÍÍÎÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÎÍÍÍÍÍÍ͹
|
|
I A º±±±±±±ºOLD SS º º±±±±±±ºOLD SS º
|
|
O N ÌÍÍÍÍÍÍÊÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÊÍÍÍÍÍÍ͹
|
|
N S º OLD ESP º º OLD ESP º
|
|
I ÌÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
|
³ O º OLD EFLAGS º º OLD EFLAGS º
|
|
³ N ÌÍÍÍÍÍÍËÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍËÍÍÍÍÍÍ͹
|
|
³ º±±±±±±ºOLD CS º NEW º±±±±±±ºOLD CS º
|
|
ÌÍÍÍÍÍÍÊÍÍÍÍÍÍ͹ SS:EIP ÌÍÍÍÍÍÍÊÍÍÍÍÍÍ͹
|
|
º OLD EIP º ³ º OLD EIP º NEW
|
|
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ÄÄÄÙ ÌÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ SS:EIP
|
|
º º º ERROR CODE º ³
|
|
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ÄÄÄÙ
|
|
º º
|
|
|
|
|
|
|
|
15.4 Additional Sensitive Instructions
|
|
|
|
When the 80386 is executing in V86 mode, the instructions PUSHF, POPF,
|
|
INT n, and IRET are sensitive to IOPL. The instructions IN, INS, OUT, and
|
|
OUTS, which are ordinarily sensitive in protected mode, are not sensitive
|
|
in V86 mode. Following is a complete list of instructions that are sensitive
|
|
in V86 mode:
|
|
|
|
CLI ÄÄ Clear Interrupt-Enable Flag
|
|
STI ÄÄ Set Interrupt-Enable Flag
|
|
LOCK ÄÄ Assert Bus-Lock Signal
|
|
PUSHF ÄÄ Push Flags
|
|
POPF ÄÄ Pop Flags
|
|
INT n ÄÄ Software Interrupt
|
|
RET ÄÄ Interrupt Return
|
|
|
|
CPL is always three in V86 mode; therefore, if IOPL < 3, these instructions
|
|
will trigger a general-protection exceptions. These instructions are made
|
|
sensitive so that their functions can be simulated by the V86 monitor.
|
|
|
|
|
|
15.4.1 Emulating 8086 Operating System Calls
|
|
|
|
INT n is sensitive so that the V86 monitor can intercept calls to the
|
|
8086 OS. Many 8086 operating systems are called by pushing parameters onto
|
|
the stack, then executing an INT n instruction. If IOPL < 3, INT n
|
|
instructions will be intercepted by the V86 monitor. The V86 monitor can
|
|
then emulate the function of the 8086 operating system or reflect the
|
|
interrupt back to the 8086 operating system in V86 mode.
|
|
|
|
|
|
15.4.2 Virtualizing the Interrupt-Enable Flag
|
|
|
|
When the processor is executing 8086 code in a V86 task, the instructions
|
|
PUSHF, POPF, and IRET are sensitive to IOPL so that the V86 monitor can
|
|
control changes to the interrupt-enable flag (IF). Other instructions that
|
|
affect IF (STI and CLI) are IOPL sensitive both in 8086 code and in
|
|
80386/80386 code.
|
|
|
|
Many 8086 programs that were designed to execute on single-task systems set
|
|
and clear IF to control interrupts. However, when these same programs are
|
|
executed in a multitasking environment, such control of IF can be
|
|
disruptive. If IOPL is less than three, all instructions that change or
|
|
interrogate IF will trap to the V86 monitor. The V86 monitor can then
|
|
control IF in a manner that both suits the needs of the larger environment
|
|
and is transparent to the 8086 program.
|
|
|
|
|
|
15.5 Virtual I/O
|
|
|
|
Many 8086 programs that were designed to execute on single-task systems use
|
|
I/O devices directly. However, when these same programs are executed in a
|
|
multitasking environment, such use of devices can be disruptive. The 80386
|
|
provides sufficient flexibility to control I/O in a manner that both suits
|
|
the needs of the new environment and is transparent to the 8086 program.
|
|
Designers may take any of several possible approaches to controlling I/O:
|
|
|
|
þ Implement or emulate the 8086 operating system as an 80386 program and
|
|
require the 8086 application to do I/O via software interrupts to the
|
|
operating system, trapping all attempts to do I/O directly.
|
|
|
|
þ Let the 8086 program take complete control of all I/O.
|
|
|
|
þ Selectively trap and emulate references that a task makes to specific
|
|
I/O ports.
|
|
|
|
þ Trap or redirect references to memory-mapped I/O addresses.
|
|
|
|
The method of controlling I/O depends upon whether I/O ports are I/O mapped
|
|
or memory mapped.
|
|
|
|
|
|
15.5.1 I/O-Mapped I/O
|
|
|
|
I/O-mapped I/O in V86 mode differs from protected mode only in that the
|
|
protection mechanism does not consult IOPL when executing the I/O
|
|
instructions IN, INS, OUT, OUTS. Only the I/O permission bit map controls
|
|
the right for V86 tasks to execute these I/O instructions.
|
|
|
|
The I/O permission map traps I/O instructions selectively depending on the
|
|
I/O addresses to which they refer. The I/O permission bit map of each V86
|
|
task determines which I/O addresses are trapped for that task. Because each
|
|
task may have a different I/O permission bit map, the addresses trapped for
|
|
one task may be different from those trapped for others. Refer to Chapter 8
|
|
for more information about the I/O permission map.
|
|
|
|
|
|
15.5.2 Memory-Mapped I/O
|
|
|
|
In hardware designs that utilize memory-mapped I/O, the paging facilities
|
|
of the 80386 can be used to trap or redirect I/O operations. Each task that
|
|
executes memory-mapped I/O must have a page (or pages) for the memory-mapped
|
|
address space. The V86 monitor may control memory-mapped I/O by any of
|
|
these means:
|
|
|
|
þ Assign the memory-mapped page to appropriate physical addresses.
|
|
Different tasks may have different physical addresses, thereby
|
|
preventing the tasks from interfering with each other.
|
|
|
|
þ Cause a trap to the monitor by forcing a page fault on the
|
|
memory-mapped page. Read-only pages trap writes. Not-present pages trap
|
|
both reads and writes.
|
|
|
|
Intervention for every I/O might be excessive for some kinds of I/O
|
|
devices. A page fault can still be used in this case to cause intervention
|
|
on the first I/O operation. The monitor can then at least make sure that the
|
|
task has exclusive access to the device. Then the monitor can change the
|
|
page status to present and read/write, allowing subsequent I/O to proceed at
|
|
full speed.
|
|
|
|
|
|
15.5.3 Special I/O Buffers
|
|
|
|
Buffers of intelligent controllers (for example, a bit-mapped graphics
|
|
buffer) can also be virtualized via page mapping. The linear space for the
|
|
buffer can be mapped to a different physical space for each virtual 8086
|
|
task. The V86 monitor can then assume responsibility for spooling the data
|
|
or assigning the virtual buffer to the real buffer at appropriate times.
|
|
|
|
|
|
15.6 Differences From 8086
|
|
|
|
In general, V86 mode will correctly execute software designed for the 8086,
|
|
8088, 80186, and 80188. Following is a list of the minor differences between
|
|
8086 execution on the 80386 and on an 8086.
|
|
|
|
1. Instruction clock counts.
|
|
|
|
The 80386 takes fewer clocks for most instructions than the
|
|
8086/8088. The areas most likely to be affected are:
|
|
|
|
þ Delays required by I/O devices between I/O operations.
|
|
|
|
þ Assumed delays with 8086/8088 operating in parallel with an 8087.
|
|
|
|
2. Divide exceptions point to the DIV instruction.
|
|
|
|
Divide exceptions on the 80386 always leave the saved CS:IP value
|
|
pointing to the instruction that failed. On the 8086/8088, the CS:IP
|
|
value points to the next instruction.
|
|
|
|
3. Undefined 8086/8088 opcodes.
|
|
|
|
Opcodes that were not defined for the 8086/8088 will cause exception
|
|
6 or will execute one of the new instructions defined for the 80386.
|
|
|
|
4. Value written by PUSH SP.
|
|
|
|
The 80386 pushes a different value on the stack for PUSH SP than the
|
|
8086/8088. The 80386 pushes the value of SP before SP is incremented
|
|
as part of the push operation; the 8086/8088 pushes the value of SP
|
|
after it is incremented. If the value pushed is important, replace
|
|
PUSH SP instructions with the following three instructions:
|
|
|
|
PUSH BP
|
|
MOV BP, SP
|
|
XCHG BP, [BP]
|
|
|
|
This code functions as the 8086/8088 PUSH SP instruction on the
|
|
80386.
|
|
|
|
5. Shift or rotate by more than 31 bits.
|
|
|
|
The 80386 masks all shift and rotate counts to the low-order five
|
|
bits. This MOD 32 operation limits the count to a maximum of 31 bits,
|
|
thereby limiting the time that interrupt response is delayed while
|
|
the instruction is executing.
|
|
|
|
6. Redundant prefixes.
|
|
|
|
The 80386 sets a limit of 15 bytes on instruction length. The only
|
|
way to violate this limit is by putting redundant prefixes before an
|
|
instruction. Exception 13 occurs if the limit on instruction length
|
|
is violated. The 8086/8088 has no instruction length limit.
|
|
|
|
7. Operand crossing offset 0 or 65,535.
|
|
|
|
On the 8086, an attempt to access a memory operand that crosses
|
|
offset 65,535 (e.g., MOV a word to offset 65,535) or offset 0 (e.g.,
|
|
PUSH a word when SP = 1) causes the offset to wrap around modulo
|
|
65,536. The 80386 raises an exception in these casesÄÄexception 13 if
|
|
the segment is a data segment (i.e., if CS, DS, ES, FS, or GS is
|
|
being used to address the segment), exception 12 if the segment is a
|
|
stack segment (i.e., if SS is being used).
|
|
|
|
8. Sequential execution across offset 65,535.
|
|
|
|
On the 8086, if sequential execution of instructions proceeds past
|
|
offset 65,535, the processor fetches the next instruction byte from
|
|
offset 0 of the same segment. On the 80386, the processor raises
|
|
exception 13 in such a case.
|
|
|
|
9. LOCK is restricted to certain instructions.
|
|
|
|
The LOCK prefix and its corresponding output signal should only be
|
|
used to prevent other bus masters from interrupting a data movement
|
|
operation. The 80386 always asserts the LOCK signal during an XCHG
|
|
instruction with memory (even if the LOCK prefix is not used). LOCK
|
|
may only be used with the following 80386 instructions when they
|
|
update memory: BTS, BTR, BTC, XCHG, ADD, ADC, SUB, SBB, INC, DEC,
|
|
AND, OR, XOR, NOT, and NEG. An undefined-opcode exception (interrupt
|
|
6) results from using LOCK before any other instruction.
|
|
|
|
10. Single-stepping external interrupt handlers.
|
|
|
|
The priority of the 80386 single-step exception is different from
|
|
that of the 8086/8088. The change prevents an external interrupt
|
|
handler from being single-stepped if the interrupt occurs while a
|
|
program is being single-stepped. The 80386 single-step exception has
|
|
higher priority that any external interrupt. The 80386 will still
|
|
single-step through an interrupt handler invoked by the INT
|
|
instructions or by an exception.
|
|
|
|
11. IDIV exceptions for quotients of 80H or 8000H.
|
|
|
|
The 80386 can generate the largest negative number as a quotient for
|
|
the IDIV instruction. The 8086/8088 causes exception zero instead.
|
|
|
|
12. Flags in stack.
|
|
|
|
The setting of the flags stored by PUSHF, by interrupts, and by
|
|
exceptions is different from that stored by the 8086 in bit positions
|
|
12 through 15. On the 8086 these bits are stored as ones, but in V86
|
|
mode bit 15 is always zero, and bits 14 through 12 reflect the last
|
|
value loaded into them.
|
|
|
|
13. NMI interrupting NMI handlers.
|
|
|
|
After an NMI is recognized on the 80386, the NMI interrupt is masked
|
|
until an IRET instruction is executed.
|
|
|
|
14. Coprocessor errors vector to interrupt 16.
|
|
|
|
Any 80386 system with a coprocessor must use interrupt vector 16 for
|
|
the coprocessor error exception. If an 8086/8088 system uses another
|
|
vector for the 8087 interrupt, both vectors should point to the
|
|
coprocessor-error exception handler.
|
|
|
|
15. Numeric exception handlers should allow prefixes.
|
|
|
|
On the 80386, the value of CS:IP saved for coprocessor exceptions
|
|
points at any prefixes before an ESC instruction. On 8086/8088
|
|
systems, the saved CS:IP points to the ESC instruction itself.
|
|
|
|
16. Coprocessor does not use interrupt controller.
|
|
|
|
The coprocessor error signal to the 80386 does not pass through an
|
|
interrupt controller (an 8087 INT signal does). Some instructions in
|
|
a coprocessor error handler may need to be deleted if they deal with
|
|
the interrupt controller.
|
|
|
|
|
|
15.7 Differences From 80286 Real-Address Mode
|
|
|
|
The 80286 processor implements the bus lock function differently than the
|
|
80386. This fact may or may not be apparent to 8086 programs, depending on
|
|
how the V86 monitor handles the LOCK prefix. LOCKed instructions are
|
|
sensitive to IOPL; therefore, software designers can choose to emulate its
|
|
function. If, however, 8086 programs are allowed to execute LOCK directly,
|
|
programs that use forms of memory locking specific to the 8086 may not
|
|
execute properly when transported to a specific application of the 80386.
|
|
|
|
The LOCK prefix and its corresponding output signal should only 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
|
|
other instruction.
|
|
|
|
þ Bit test and change: BTS, BTR, BTC.
|
|
þ Exchange: XCHG.
|
|
þ One-operand arithmetic and logical: INC, DEC, NOT, and NEG.
|
|
þ Two-operand arithmetic and logical: ADD, ADC, SUB, SBB, AND, OR, XOR.
|
|
|
|
A locked instruction is guaranteed to lock only the area of memory defined
|
|
by the destination operand, but may lock a larger memory area. For example,
|
|
typical 8086 and 80286 configurations lock the entire physical memory space.
|
|
With the 80386, the defined area of memory 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.
|
|
|
|
|
|
Chapter 16 Mixing 16-Bit and 32 Bit Code
|
|
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
|
|
The 80386 running in protected mode is a 32-bit microprocessor, but it is
|
|
designed to support 16-bit processing at three levels:
|
|
|
|
1. Executing 8086/80286 16-bit programs efficiently with complete
|
|
compatibility.
|
|
|
|
2. Mixing 16-bit modules with 32-bit modules.
|
|
|
|
3. Mixing 16-bit and 32-bit addresses and operands within one module.
|
|
|
|
The first level of support for 16-bit programs has already been discussed
|
|
in Chapter 13, Chapter 14, and Chapter 15. This chapter shows how 16-bit
|
|
and 32-bit modules can cooperate with one another, and how one module can
|
|
utilize both 16-bit and 32-bit operands and addressing.
|
|
|
|
The 80386 functions most efficiently when it is possible to distinguish
|
|
between pure 16-bit modules and pure 32-bit modules. A pure 16-bit module
|
|
has these characteristics:
|
|
|
|
þ All segments occupy 64 Kilobytes or less.
|
|
þ Data items are either 8 bits or 16 bits wide.
|
|
þ Pointers to code and data have 16-bit offsets.
|
|
þ Control is transferred only among 16-bit segments.
|
|
|
|
A pure 32-bit module has these characteristics:
|
|
|
|
þ Segments may occupy more than 64 Kilobytes (zero bytes to 4
|
|
gigabytes).
|
|
|
|
þ Data items are either 8 bits or 32 bits wide.
|
|
|
|
þ Pointers to code and data have 32-bit offsets.
|
|
|
|
þ Control is transferred only among 32-bit segments.
|
|
|
|
Pure 16-bit modules do exist; they are the modules designed for 16-bit
|
|
microprocessors. Pure 32-bit modules may exist in new programs designed
|
|
explicitly for the 80386. However, as systems designers move applications
|
|
from 16-bit processors to the 32-bit 80386, it will not always be possible
|
|
to maintain these ideals of pure 16-bit or 32-bit modules. It may be
|
|
expedient to execute old 16-bit modules in a new 32-bit environment without
|
|
making source-code changes to the old modules if any of the following
|
|
conditions is true:
|
|
|
|
þ Modules will be converted one-by-one from 16-bit environments to
|
|
32-bit environments.
|
|
|
|
þ Older, 16-bit compilers and software-development tools will be
|
|
utilized in the new32-bit operating environment until new 32-bit
|
|
versions can be created.
|
|
|
|
þ The source code of 16-bit modules is not available for modification.
|
|
|
|
þ The specific data structures used by a given module inherently utilize
|
|
16-bit words.
|
|
|
|
þ The native word size of the source language is 16 bits.
|
|
|
|
On the 80386, 16-bit modules can be mixed with 32-bit modules. To design a
|
|
system that mixes 16- and 32-bit code requires an understanding of the
|
|
mechanisms that the 80386 uses to invoke and control its 32-bit and 16-bit
|
|
features.
|
|
|
|
|
|
16.1 How the 80386 Implements 16-Bit and 32-Bit Features
|
|
|
|
The features of the architecture that permit the 80386 to work equally well
|
|
with 32-bit and 16-bit address and operand sizes include:
|
|
|
|
þ The D-bit (default bit) of code-segment descriptors, which determines
|
|
the default choice of operand-size and address-size for the
|
|
instructions of a code segment. (In real-address mode and V86 mode,
|
|
which do not use descriptors, the default is 16 bits.) A code segment
|
|
whose D-bit is set is known as a USE32 segment; a code segment whose
|
|
D-bit is zero is a USE16 segment. The D-bit eliminates the need to
|
|
encode the operand size and address size in instructions when all
|
|
instructions use operands and effective addresses of the same size.
|
|
|
|
þ Instruction prefixes that explicitly override the default choice of
|
|
operand size and address size (available in protected mode as well as
|
|
in real-address mode and V86 mode).
|
|
|
|
þ Separate 32-bit and 16-bit gates for intersegment control transfers
|
|
(including call gates, interrupt gates, and trap gates). The operand
|
|
size for the control transfer is determined by the type of gate, not by
|
|
the D-bit or prefix of the transfer instruction.
|
|
|
|
þ Registers that can be used both for 32-bit and 16-bit operands and
|
|
effective-address calculations.
|
|
|
|
þ The B-bit (big bit) of data-segment descriptors, which determines the
|
|
size of stack pointer (32-bit ESP or 16-bit SP) used by the CPU for
|
|
implicit stack references.
|
|
|
|
|
|
16.2 Mixing 32-Bit and 16-Bit Operations
|
|
|
|
The 80386 has two instruction prefixes that allow mixing of 32-bit and
|
|
16-bit operations within one segment:
|
|
|
|
þ The operand-size prefix (66H)
|
|
þ The address-size prefix (67H)
|
|
|
|
These prefixes reverse the default size selected by the D-bit. For example,
|
|
the processor can interpret the word-move instruction MOV mem, reg in any of
|
|
four ways:
|
|
|
|
þ In a USE32 segment:
|
|
|
|
1. Normally moves 32 bits from a 32-bit register to a 32-bit
|
|
effective address in memory.
|
|
|
|
2. If preceded by an operand-size prefix, moves 16 bits from a 16-bit
|
|
register to 32-bit effective address in memory.
|
|
|
|
3. If preceded by an address-size prefix, moves 32 bits from a 32-bit
|
|
register to a16-bit effective address in memory.
|
|
|
|
4. If preceded by both an address-size prefix and an operand-size
|
|
prefix, moves 16 bits from a 16-bit register to a 16-bit effective
|
|
address in memory.
|
|
|
|
þ In a USE16 segment:
|
|
|
|
1. Normally moves 16 bits from a 16-bit register to a 16-bit
|
|
effective address in memory.
|
|
|
|
2. If preceded by an operand-size prefix, moves 32 bits from a 32-bit
|
|
register to 16-bit effective address in memory.
|
|
|
|
3. If preceded by an address-size prefix, moves 16 bits from a 16-bit
|
|
register to a32-bit effective address in memory.
|
|
|
|
4. If preceded by both an address-size prefix and an operand-size
|
|
prefix, moves 32 bits from a 32-bit register to a 32-bit effective
|
|
address in memory.
|
|
|
|
These examples illustrate that any instruction can generate any combination
|
|
of operand size and address size regardless of whether the instruction is in
|
|
a USE16 or USE32 segment. The choice of the USE16 or USE32 attribute for a
|
|
code segment is based upon these criteria:
|
|
|
|
1. The need to address instructions or data in segments that are larger
|
|
than 64 Kilobytes.
|
|
|
|
2. The predominant size of operands.
|
|
|
|
3. The addressing modes desired. (Refer to Chapter 17 for an explanation
|
|
of the additional addressing modes that are available when 32-bit
|
|
addressing is used.)
|
|
|
|
Choosing a setting of the D-bit that is contrary to the predominant size of
|
|
operands requires the generation of an excessive number of operand-size
|
|
prefixes.
|
|
|
|
|
|
16.3 Sharing Data Segments Among Mixed Code Segments
|
|
|
|
Because the choice of operand size and address size is defined in code
|
|
segments and their descriptors, data segments can be shared freely among
|
|
both USE16 and USE32 code segments. The only limitation is the one imposed
|
|
by pointers with 16-bit offsets, which can only point to the first 64
|
|
Kilobytes of a segment. When a data segment that contains more than 64
|
|
Kilobytes is to be shared among USE32 and USE16 segments, the data that is
|
|
to be accessed by the USE16 segments must be located within the first 64
|
|
Kilobytes.
|
|
|
|
A stack that spans addresses less than 64K can be shared by both USE16 and
|
|
USE32 code segments. This class of stacks includes:
|
|
|
|
þ Stacks in expand-up segments with G=0 and B=0.
|
|
|
|
þ Stacks in expand-down segments with G=0 and B=0.
|
|
|
|
þ Stacks in expand-up segments with G=1 and B=0, in which the stack is
|
|
contained completely within the lower 64 Kilobytes. (Offsets greater
|
|
than 64K can be used for data, other than the stack, that is not
|
|
shared.)
|
|
|
|
The B-bit of a stack segment cannot, in general, be used to change the size
|
|
of stack used by a USE16 code segment. The size of stack pointer used by the
|
|
processor for implicit stack references is controlled by the B-bit of the
|
|
data-segment descriptor for the stack. Implicit references are those caused
|
|
by interrupts, exceptions, and instructions such as PUSH, POP, CALL, and
|
|
RET. One might be tempted, therefore, to try to increase beyond 64K the
|
|
size of the stack used by 16-bit code simply by supplying a larger stack
|
|
segment with the B-bit set. However, the B-bit does not control explicit
|
|
stack references, such as accesses to parameters or local variables. A USE16
|
|
code segment can utilize a "big" stack only if the code is modified so that
|
|
all explicit references to the stack are preceded by the address-size
|
|
prefix, causing those references to use 32-bit addressing.
|
|
|
|
In big, expand-down segments (B=1, G=1, and E=1), all offsets are greater
|
|
than 64K, therefore USE16 code cannot utilize such a stack segment unless
|
|
the code segment is modified to employ 32-bit addressing. (Refer to Chapter
|
|
6 for a review of the B, G, and E bits.)
|
|
|
|
|
|
16.4 Transferring Control Among Mixed Code Segments
|
|
|
|
When transferring control among procedures in USE16 and USE32 code
|
|
segments, programmers must be aware of three points:
|
|
|
|
þ Addressing limitations imposed by pointers with 16-bit offsets.
|
|
|
|
þ Matching of operand-size attribute in effect for the CALL/RET pair and
|
|
theInterrupt/IRET pair so as to manage the stack correctly.
|
|
|
|
þ Translation of parameters, especially pointer parameters.
|
|
|
|
Clearly, 16-bit effective addresses cannot be used to address data or code
|
|
located beyond 64K in a 32-bit segment, nor can large 32-bit parameters be
|
|
squeezed into a 16-bit word; however, except for these obvious limits, most
|
|
interfacing problems between 16-bit and 32-bit modules can be solved. Some
|
|
solutions involve inserting interface procedures between the procedures in
|
|
question.
|
|
|
|
|
|
16.4.1 Size of Code-Segment Pointer
|
|
|
|
For control-transfer instructions that use a pointer to identify the next
|
|
instruction (i.e., those that do not use gates), the size of the offset
|
|
portion of the pointer is determined by the operand-size attribute. The
|
|
implications of the use of two different sizes of code-segment pointer are:
|
|
|
|
þ JMP, CALL, or RET from 32-bit segment to 16-bit segment is always
|
|
possible using a 32-bit operand size.
|
|
|
|
þ JMP, CALL, or RET from 16-bit segment using a 16-bit operand size
|
|
cannot address the target in a 32-bit segment if the address of the
|
|
target is greater than 64K.
|
|
|
|
An interface procedure can enable transfers from USE16 segments to 32-bit
|
|
addresses beyond 64K without requiring modifications any more extensive than
|
|
relinking or rebinding the old programs. The requirements for such an
|
|
interface procedure are discussed later in this chapter.
|
|
|
|
|
|
16.4.2 Stack Management for Control Transfers
|
|
|
|
Because stack management is different for 16-bit CALL/RET than for 32-bit
|
|
CALL/RET, the operand size of RET must match that of CALL. (Refer to Figure
|
|
16-1.) A 16-bit CALL pushes the 16-bit IP and (for calls between privilege
|
|
levels) the 16-bit SP register. The corresponding RET must also use a 16-bit
|
|
operand size to POP these 16-bit values from the stack into the 16-bit
|
|
registers. A 32-bit CALL pushes the 32-bit EIP and (for interlevel calls)
|
|
the 32-bit ESP register. The corresponding RET must also use a 32-bit
|
|
operand size to POP these 32-bit values from the stack into the 32-bit
|
|
registers. If the two halves of a CALL/RET pair do not have matching operand
|
|
sizes, the stack will not be managed correctly and the values of the
|
|
instruction pointer and stack pointer will not be restored to correct
|
|
values.
|
|
|
|
When the CALL and its corresponding RET are in segments that have D-bits
|
|
with the same values (i.e., both have 32-bit defaults or both have 16-bit
|
|
defaults), there is no problem. When the CALL and its corresponding RET are
|
|
in segments that have different D-bit values, however, programmers (or
|
|
program development software) must ensure that the CALL and RET match.
|
|
|
|
There are three ways to cause a 16-bit procedure to execute a 32-bit call:
|
|
|
|
1. Use a 16-bit call to a 32-bit interface procedure that then uses a
|
|
32-bit call to invoke the intended target.
|
|
|
|
2. Bind the 16-bit call to a 32-bit call gate.
|
|
|
|
3. Modify the 16-bit procedure, inserting an operand-size prefix before
|
|
the call, thereby changing it to a 32-bit call.
|
|
|
|
Likewise, there are three ways to cause a 32-bit procedure to execute a
|
|
16-bit call:
|
|
|
|
1. Use a 32-bit call to a 32-bit interface procedure that then uses a
|
|
16-bit call to invoke the intended target.
|
|
|
|
2. Bind the 32-bit call to a 16-bit call gate.
|
|
|
|
3. Modify the 32-bit procedure, inserting an operand-size prefix before
|
|
the call, thereby changing it to a 16-bit call. (Be certain that the
|
|
return offset does not exceed 64K.)
|
|
|
|
Programmers can utilize any of the preceding methods to make a CALL in a
|
|
USE16 segment match the corresponding RET in a USE32 segment, or to make a
|
|
CALL in a USE32 segment match the corresponding RET in a USE16 segment.
|
|
|
|
|
|
Figure 16-1. Stack after Far 16-Bit and 32-Bit Calls
|
|
|
|
WITHOUT PRIVILEGE TRANSITION
|
|
|
|
AFTER 16-BIT CALL AFTER 32-BIT CALL
|
|
|
|
31 0 31 0
|
|
D O º º º º
|
|
I F ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
|
R º±±±±±±±±±±±±±±±º º±±±±±±±±±±±±±±±º
|
|
E E ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
|
C X º PARM2 ³ PARM1 º º PARM2 º
|
|
T P ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
|
I A º CS ³ IP ºÄÄSP º PARM1 º
|
|
O N ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
|
N S º º º±±±±±±±³ CS º
|
|
I ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
|
³ O º º º EIP ºÄÄESP
|
|
³ N ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
|
³ º º º º
|
|
|
|
|
|
WITH PRIVILEGE TRANSITION
|
|
|
|
AFTER 16-BIT CALL AFTER 32-BIT CALL
|
|
|
|
D O 31 0 31 0
|
|
I F ÉÍÍÍÍÍÍÍØÍÍÍÍÍÍÍ» ÉÍÍÍÍÍÍÍØÍÍÍÍÍÍÍ»
|
|
R º SS ³ SP º º±±±±±±±³ SS º
|
|
E E ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
|
C X º PARM2 ³ PARM1 º º ESP º
|
|
T P ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
|
I A º CS ³ IP ºÄÄSP º PARM2 º
|
|
O N ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
|
N S º º º PARM1 º
|
|
I ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
|
³ O º º º±±±±±±±³ CS º
|
|
³ N ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
|
³ º º º EIP ºÄÄESP
|
|
ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
|
|
º º º º
|
|
|
|
|
|
|
|
16.4.2.1 Controlling the Operand-Size for a Call
|
|
|
|
When the selector of the pointer referenced by a CALL instruction selects a
|
|
segment descriptor, the operand-size attribute in effect for the CALL
|
|
instruction is determined by the D-bit in the segment descriptor and by any
|
|
operand-size instruction prefix.
|
|
|
|
When the selector of the pointer referenced by a CALL instruction selects a
|
|
gate descriptor, the type of call is determined by the type of call gate. A
|
|
call via an 80286 call gate (descriptor type 4) always has a 16-bit
|
|
operand-size attribute; a call via an 80386 call gate (descriptor type 12)
|
|
always has a 32-bit operand-size attribute. The offset of the target
|
|
procedure is taken from the gate descriptor; therefore, even a 16-bit
|
|
procedure can call a procedure that is located more than 64 kilobytes from
|
|
the base of a 32-bit segment, because a 32-bit call gate contains a 32-bit
|
|
target offset.
|
|
|
|
An unmodified 16-bit code segment that has run successfully on an 8086 or
|
|
real-mode 80286 will always have a D-bit of zero and will not use
|
|
operand-size override prefixes; therefore, it will always execute 16-bit
|
|
versions of CALL. The only modification needed to make a16-bit procedure
|
|
effect a 32-bit call is to relink the call to an 80386 call gate.
|
|
|
|
|
|
16.4.2.2 Changing Size of Call
|
|
|
|
When adding 32-bit gates to 16-bit procedures, it is important to consider
|
|
the number of parameters. The count field of the gate descriptor specifies
|
|
the size of the parameter string to copy from the current stack to the stack
|
|
of the more privileged procedure. The count field of a 16-bit gate specifies
|
|
the number of words to be copied, whereas the count field of a 32-bit gate
|
|
specifies the number of doublewords to be copied; therefore, the 16-bit
|
|
procedure must use an even number of words as parameters.
|
|
|
|
|
|
16.4.3 Interrupt Control Transfers
|
|
|
|
With a control transfer due to an interrupt or exception, a gate is always
|
|
involved. The operand-size attribute for the interrupt is determined by the
|
|
type of IDT gate.
|
|
|
|
A 386 interrupt or trap gate (descriptor type 14 or 15) to a 32-bit
|
|
interrupt procedure can be used to interrupt either 32-bit or 16-bit
|
|
procedures. However, it is not generally feasible to permit an interrupt or
|
|
exception to invoke a 16-bit handler procedure when 32-bit code is
|
|
executing, because a 16-bit interrupt procedure has a return offset of only
|
|
16-bits on its stack. If the 32-bit procedure is executing at an address
|
|
greater than 64K, the 16-bit interrupt procedure cannot return correctly.
|
|
|
|
|
|
16.4.4 Parameter Translation
|
|
|
|
When segment offsets or pointers (which contain segment offsets) are passed
|
|
as parameters between 16-bit and 32-bit procedures, some translation is
|
|
required. Clearly, if a 32-bit procedure passes a pointer to data located
|
|
beyond 64K to a 16-bit procedure, the 16-bit procedure cannot utilize it.
|
|
Beyond this natural limitation, an interface procedure can perform any
|
|
format conversion between 32-bit and 16-bit pointers that may be needed.
|
|
|
|
Parameters passed by value between 32-bit and 16-bit code may also require
|
|
translation between 32-bit and 16-bit formats. Such translation requirements
|
|
are application dependent. Systems designers should take care to limit the
|
|
range of values passed so that such translations are possible.
|
|
|
|
|
|
16.4.5 The Interface Procedure
|
|
|
|
Interposing an interface procedure between 32-bit and 16-bit procedures can
|
|
be the solution to any of several interface requirements:
|
|
|
|
þ Allowing procedures in 16-bit segments to transfer control to
|
|
instructions located beyond 64K in 32-bit segments.
|
|
|
|
þ Matching of operand size for CALL/RET.
|
|
|
|
þ Parameter translation.
|
|
|
|
Interface procedures between USE32 and USE16 segments can be constructed
|
|
with these properties:
|
|
|
|
þ The procedures reside in a code segment whose D-bit is set, indicating
|
|
a default operand size of 32-bits.
|
|
|
|
þ All entry points that may be called by 16-bit procedures have offsets
|
|
that are actually less than 64K.
|
|
|
|
þ All points to which called 16-bit procedures may return also lie
|
|
within 64K.
|
|
|
|
The interface procedures do little more than call corresponding procedures
|
|
in other segments. There may be two kinds of procedures:
|
|
|
|
þ Those that are called by 16-bit procedures and call 32-bit procedures.
|
|
These interface procedures are called by 16-bit CALLs and use the
|
|
operand-size prefix before RET instructions to cause a 16-bit RET.
|
|
CALLs to 32-bit segments are 32-bit calls (by default, because the
|
|
D-bit is set), and the 32-bit code returns with 32-bit RET
|
|
instructions.
|
|
|
|
þ Those that are called by 32-bit procedures and call 16-bit procedures.
|
|
These interface procedures are called by 32-bit CALL instructions, and
|
|
return with 32-bit RET instructions (by default, because the D-bit is
|
|
set). CALLs to 16-bit procedures use the operand-size prefix;
|
|
procedures in the 16-bit code return with 16-bit RET instructions.
|
|
|
|
|
|
PART IV INSTRUCTION SET
|
|
|
|
|
|
Chapter 17 80386 Instruction Set
|
|
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
|
|
This chapter presents instructions for the 80386 in alphabetical order. For
|
|
each instruction, the forms are given for each operand combination,
|
|
including object code produced, operands required, execution time, and a
|
|
description. For each instruction, there is an operational description and a
|
|
summary of exceptions generated.
|
|
|
|
|
|
17.1 Operand-Size and Address-Size Attributes
|
|
|
|
When executing an instruction, the 80386 can address memory using either 16
|
|
or 32-bit addresses. Consequently, each instruction that uses memory
|
|
addresses has associated with it an address-size attribute of either 16 or
|
|
32 bits. 16-bit addresses imply both the use of a 16-bit displacement in
|
|
the instruction and the generation of a 16-bit address offset (segment
|
|
relative address) as the result of the effective address calculation.
|
|
32-bit addresses imply the use of a 32-bit displacement and the generation
|
|
of a 32-bit address offset. Similarly, an instruction that accesses words
|
|
(16 bits) or doublewords (32 bits) has an operand-size attribute of either
|
|
16 or 32 bits.
|
|
|
|
The attributes are determined by a combination of defaults, instruction
|
|
prefixes, and (for programs executing in protected mode) size-specification
|
|
bits in segment descriptors.
|
|
|
|
|
|
17.1.1 Default Segment Attribute
|
|
|
|
For programs executed in protected mode, the D-bit in executable-segment
|
|
descriptors determines the default attribute for both address size and
|
|
operand size. These default attributes apply to the execution of all
|
|
instructions in the segment. A value of zero in the D-bit sets the default
|
|
address size and operand size to 16 bits; a value of one, to 32 bits.
|
|
|
|
Programs that execute in real mode or virtual-8086 mode have 16-bit
|
|
addresses and operands by default.
|
|
|
|
|
|
17.1.2 Operand-Size and Address-Size Instruction Prefixes
|
|
|
|
The internal encoding of an instruction can include two byte-long prefixes:
|
|
the address-size prefix, 67H, and the operand-size prefix, 66H. (A later
|
|
section, "Instruction Format," shows the position of the prefixes in an
|
|
instruction's encoding.) These prefixes override the default segment
|
|
attributes for the instruction that follows. Table 17-1 shows the effect of
|
|
each possible combination of defaults and overrides.
|
|
|
|
|
|
17.1.3 Address-Size Attribute for Stack
|
|
|
|
Instructions that use the stack implicitly (for example: POP EAX also have
|
|
a stack address-size attribute of either 16 or 32 bits. Instructions with a
|
|
stack address-size attribute of 16 use the 16-bit SP stack pointer register;
|
|
instructions with a stack address-size attribute of 32 bits use the 32-bit
|
|
ESP register to form the address of the top of the stack.
|
|
|
|
The stack address-size attribute is controlled by the B-bit of the
|
|
data-segment descriptor in the SS register. A value of zero in the B-bit
|
|
selects a stack address-size attribute of 16; a value of one selects a stack
|
|
address-size attribute of 32.
|
|
|
|
|
|
Table 17-1. Effective Size Attributes
|
|
|
|
Segment Default D = ... 0 0 0 0 1 1 1 1
|
|
Operand-Size Prefix 66H N N Y Y N N Y Y
|
|
Address-Size Prefix 67H N Y N Y N Y N Y
|
|
|
|
Effective Operand Size 16 16 32 32 32 32 16 16
|
|
Effective Address Size 16 32 16 32 32 16 32 16
|
|
|
|
Y = Yes, this instruction prefix is present
|
|
N = No, this instruction prefix is not present
|
|
|
|
|
|
17.2 Instruction Format
|
|
|
|
All instruction encodings are subsets of the general instruction format
|
|
shown in Figure 17-1. Instructions consist of optional instruction
|
|
prefixes, one or two primary opcode bytes, possibly an address specifier
|
|
consisting of the ModR/M byte and the SIB (Scale Index Base) byte, a
|
|
displacement, if required, and an immediate data field, if required.
|
|
|
|
Smaller encoding fields can be defined within the primary opcode or
|
|
opcodes. These fields define the direction of the operation, the size of the
|
|
displacements, the register encoding, or sign extension; encoding fields
|
|
vary depending on the class of operation.
|
|
|
|
Most instructions that can refer to an operand in memory have an addressing
|
|
form byte following the primary opcode byte(s). This byte, called the ModR/M
|
|
byte, specifies the address form to be used. Certain encodings of the ModR/M
|
|
byte indicate a second addressing byte, the SIB (Scale Index Base) byte,
|
|
which follows the ModR/M byte and is required to fully specify the
|
|
addressing form.
|
|
|
|
Addressing forms can include a displacement immediately following either
|
|
the ModR/M or SIB byte. If a displacement is present, it can be 8-, 16- or
|
|
32-bits.
|
|
|
|
If the instruction specifies an immediate operand, the immediate operand
|
|
always follows any displacement bytes. The immediate operand, if specified,
|
|
is always the last field of the instruction.
|
|
|
|
The following are the allowable instruction prefix codes:
|
|
|
|
F3H REP prefix (used only with string instructions)
|
|
F3H REPE/REPZ prefix (used only with string instructions
|
|
F2H REPNE/REPNZ prefix (used only with string instructions)
|
|
F0H LOCK prefix
|
|
|
|
The following are the segment override prefixes:
|
|
|
|
2EH CS segment override prefix
|
|
36H SS segment override prefix
|
|
3EH DS segment override prefix
|
|
26H ES segment override prefix
|
|
64H FS segment override prefix
|
|
65H GS segment override prefix
|
|
66H Operand-size override
|
|
67H Address-size override
|
|
|
|
|
|
Figure 17-1. 80386 Instruction Format
|
|
|
|
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
|
º INSTRUCTION º ADDRESS- º OPERAND- º SEGMENT º
|
|
º PREFIX º SIZE PREFIX º SIZE PREFIX º OVERRIDE º
|
|
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
|
º 0 OR 1 0 OR 1 0 OR 1 0 OR 1 º
|
|
ÇÄ Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä¶
|
|
º NUMBER OF BYTES º
|
|
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
|
|
|
ÉÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
|
º OPCODE º MODR/M º SIB º DISPLACEMENT º IMMEDIATE º
|
|
º º º º º º
|
|
ÌÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
|
º 1 OR 2 0 OR 1 0 OR 1 0,1,2 OR 4 0,1,2 OR 4 º
|
|
ÇÄ Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä¶
|
|
º NUMBER OF BYTES º
|
|
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
|
|
|
|
|
17.2.1 ModR/M and SIB Bytes
|
|
|
|
The ModR/M and SIB bytes follow the opcode byte(s) in many of the 80386
|
|
instructions. They contain the following information:
|
|
|
|
þ The indexing type or register number to be used in the instruction
|
|
þ The register to be used, or more information to select the instruction
|
|
þ The base, index, and scale information
|
|
|
|
The ModR/M byte contains three fields of information:
|
|
|
|
þ The mod field, which occupies the two most significant bits of the
|
|
byte, combines with the r/m field to form 32 possible values: eight
|
|
registers and 24 indexing modes
|
|
|
|
þ The reg field, which occupies the next three bits following the mod
|
|
field, specifies either a register number or three more bits of opcode
|
|
information. The meaning of the reg field is determined by the first
|
|
(opcode) byte of the instruction.
|
|
|
|
þ The r/m field, which occupies the three least significant bits of the
|
|
byte, can specify a register as the location of an operand, or can form
|
|
part of the addressing-mode encoding in combination with the field as
|
|
described above
|
|
|
|
The based indexed and scaled indexed forms of 32-bit addressing require the
|
|
SIB byte. The presence of the SIB byte is indicated by certain encodings of
|
|
the ModR/M byte. The SIB byte then includes the following fields:
|
|
|
|
þ The ss field, which occupies the two most significant bits of the
|
|
byte, specifies the scale factor
|
|
|
|
þ The index field, which occupies the next three bits following the ss
|
|
field and specifies the register number of the index register
|
|
|
|
þ The base field, which occupies the three least significant bits of the
|
|
byte, specifies the register number of the base register
|
|
|
|
Figure 17-2 shows the formats of the ModR/M and SIB bytes.
|
|
|
|
The values and the corresponding addressing forms of the ModR/M and SIB
|
|
bytes are shown in Tables 17-2, 17-3, and 17-4. The 16-bit addressing
|
|
forms specified by the ModR/M byte are in Table 17-2. The 32-bit addressing
|
|
forms specified by ModR/M are in Table 17-3. Table 17-4 shows the 32-bit
|
|
addressing forms specified by the SIB byte
|
|
|
|
|
|
Figure 17-2. ModR/M and SIB Byte Formats
|
|
|
|
MODR/M BYTE
|
|
|
|
7 6 5 4 3 2 1 0
|
|
ÉÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
|
º MOD º REG/OPCODE º R/M º
|
|
ÈÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
|
|
|
SIB (SCALE INDEX BASE) BYTE
|
|
|
|
7 6 5 4 3 2 1 0
|
|
ÉÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
|
º SS º INDEX º BASE º
|
|
ÈÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
|
|
|
|
|
Table 17-2. 16-Bit Addressing Forms with the ModR/M Byte
|
|
|
|
|
|
r8(/r) AL CL DL BL AH CH DH BH
|
|
r16(/r) AX CX DX BX SP BP SI DI
|
|
r32(/r) EAX ECX EDX EBX ESP EBP ESI EDI
|
|
/digit (Opcode) 0 1 2 3 4 5 6 7
|
|
REG = 000 001 010 011 100 101 110 111
|
|
|
|
Effective
|
|
ÚÄÄÄAddress
|
|
disp8 denotes an 8-bit displacement following the ModR/M byte, to be
|
|
sign-extended and added to the index. disp16 denotes a 16-bit displacement
|
|
following the ModR/M byte, to be added to the index. Default segment
|
|
register is SS for the effective addresses containing a BP index, DS for
|
|
other effective addresses.ÄÄ¿ ÚMod R/M¿ ÚÄÄÄÄÄÄÄÄModR/M Values in HexadecimalÄÄÄÄÄÄÄÄ¿
|
|
|
|
[BX + SI] 000 00 08 10 18 20 28 30 38
|
|
[BX + DI] 001 01 09 11 19 21 29 31 39
|
|
[BP + SI] 010 02 0A 12 1A 22 2A 32 3A
|
|
[BP + DI] 011 03 0B 13 1B 23 2B 33 3B
|
|
[SI] 00 100 04 0C 14 1C 24 2C 34 3C
|
|
[DI] 101 05 0D 15 1D 25 2D 35 3D
|
|
disp16 110 06 0E 16 1E 26 2E 36 3E
|
|
[BX] 111 07 0F 17 1F 27 2F 37 3F
|
|
|
|
[BX+SI]+disp8 000 40 48 50 58 60 68 70 78
|
|
[BX+DI]+disp8 001 41 49 51 59 61 69 71 79
|
|
[BP+SI]+disp8 010 42 4A 52 5A 62 6A 72 7A
|
|
[BP+DI]+disp8 011 43 4B 53 5B 63 6B 73 7B
|
|
[SI]+disp8 01 100 44 4C 54 5C 64 6C 74 7C
|
|
[DI]+disp8 101 45 4D 55 5D 65 6D 75 7D
|
|
[BP]+disp8 110 46 4E 56 5E 66 6E 76 7E
|
|
[BX]+disp8 111 47 4F 57 5F 67 6F 77 7F
|
|
|
|
[BX+SI]+disp16 000 80 88 90 98 A0 A8 B0 B8
|
|
[BX+DI]+disp16 001 81 89 91 99 A1 A9 B1 B9
|
|
[BX+SI]+disp16 010 82 8A 92 9A A2 AA B2 BA
|
|
[BX+DI]+disp16 011 83 8B 93 9B A3 AB B3 BB
|
|
[SI]+disp16 10 100 84 8C 94 9C A4 AC B4 BC
|
|
[DI]+disp16 101 85 8D 95 9D A5 AD B5 BD
|
|
[BP]+disp16 110 86 8E 96 9E A6 AE B6 BE
|
|
[BX]+disp16 111 87 8F 97 9F A7 AF B7 BF
|
|
|
|
EAX/AX/AL 000 C0 C8 D0 D8 E0 E8 F0 F8
|
|
ECX/CX/CL 001 C1 C9 D1 D9 E1 E9 F1 F9
|
|
EDX/DX/DL 010 C2 CA D2 DA E2 EA F2 FA
|
|
EBX/BX/BL 011 C3 CB D3 DB E3 EB F3 FB
|
|
ESP/SP/AH 11 100 C4 CC D4 DC E4 EC F4 FC
|
|
EBP/BP/CH 101 C5 CD D5 DD E5 ED F5 FD
|
|
ESI/SI/DH 110 C6 CE D6 DE E6 EE F6 FE
|
|
EDI/DI/BH 111 C7 CF D7 DF E7 EF F7 FF
|
|
|
|
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
NOTES:
|
|
disp8 denotes an 8-bit displacement following the ModR/M byte, to be
|
|
sign-extended and added to the index. disp16 denotes a 16-bit displacement
|
|
following the ModR/M byte, to be added to the index. Default segment
|
|
register is SS for the effective addresses containing a BP index, DS for
|
|
other effective addresses.
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
|
|
|
|
Table 17-3. 32-Bit Addressing Forms with the ModR/M Byte
|
|
|
|
|
|
r8(/r) AL CL DL BL AH CH DH BH
|
|
r16(/r) AX CX DX BX SP BP SI DI
|
|
r32(/r) EAX ECX EDX EBX ESP EBP ESI EDI
|
|
/digit (Opcode) 0 1 2 3 4 5 6 7
|
|
REG = 000 001 010 011 100 101 110 111
|
|
|
|
Effective
|
|
ÚÄÄÄAddress
|
|
[--] [--] means a SIB follows the ModR/M byte. disp8 denotes an 8-bit
|
|
displacement following the SIB byte, to be sign-extended and added to the
|
|
index. disp32 denotes a 32-bit displacement following the ModR/M byte, to
|
|
be added to the index.ÄÄ¿ ÚMod R/M¿ ÚÄÄÄÄÄÄÄÄÄModR/M Values in HexadecimalÄÄÄÄÄÄÄ¿
|
|
|
|
[EAX] 000 00 08 10 18 20 28 30 38
|
|
[ECX] 001 01 09 11 19 21 29 31 39
|
|
[EDX] 010 02 0A 12 1A 22 2A 32 3A
|
|
[EBX] 011 03 0B 13 1B 23 2B 33 3B
|
|
[--] [--] 00 100 04 0C 14 1C 24 2C 34 3C
|
|
disp32 101 05 0D 15 1D 25 2D 35 3D
|
|
[ESI] 110 06 0E 16 1E 26 2E 36 3E
|
|
[EDI] 111 07 0F 17 1F 27 2F 37 3F
|
|
|
|
disp8[EAX] 000 40 48 50 58 60 68 70 78
|
|
disp8[ECX] 001 41 49 51 59 61 69 71 79
|
|
disp8[EDX] 010 42 4A 52 5A 62 6A 72 7A
|
|
disp8[EPX]; 011 43 4B 53 5B 63 6B 73 7B
|
|
disp8[--] [--] 01 100 44 4C 54 5C 64 6C 74 7C
|
|
disp8[ebp] 101 45 4D 55 5D 65 6D 75 7D
|
|
disp8[ESI] 110 46 4E 56 5E 66 6E 76 7E
|
|
disp8[EDI] 111 47 4F 57 5F 67 6F 77 7F
|
|
|
|
disp32[EAX] 000 80 88 90 98 A0 A8 B0 B8
|
|
disp32[ECX] 001 81 89 91 99 A1 A9 B1 B9
|
|
disp32[EDX] 010 82 8A 92 9A A2 AA B2 BA
|
|
disp32[EBX] 011 83 8B 93 9B A3 AB B3 BB
|
|
disp32[--] [--] 10 100 84 8C 94 9C A4 AC B4 BC
|
|
disp32[EBP] 101 85 8D 95 9D A5 AD B5 BD
|
|
disp32[ESI] 110 86 8E 96 9E A6 AE B6 BE
|
|
disp32[EDI] 111 87 8F 97 9F A7 AF B7 BF
|
|
|
|
EAX/AX/AL 000 C0 C8 D0 D8 E0 E8 F0 F8
|
|
ECX/CX/CL 001 C1 C9 D1 D9 E1 E9 F1 F9
|
|
EDX/DX/DL 010 C2 CA D2 DA E2 EA F2 FA
|
|
EBX/BX/BL 011 C3 CB D3 DB E3 EB F3 FB
|
|
ESP/SP/AH 11 100 C4 CC D4 DC E4 EC F4 FC
|
|
EBP/BP/CH 101 C5 CD D5 DD E5 ED F5 FD
|
|
ESI/SI/DH 110 C6 CE D6 DE E6 EE F6 FE
|
|
EDI/DI/BH 111 C7 CF D7 DF E7 EF F7 FF
|
|
|
|
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
NOTES:
|
|
[--] [--] means a SIB follows the ModR/M byte. disp8 denotes an 8-bit
|
|
displacement following the SIB byte, to be sign-extended and added to the
|
|
index. disp32 denotes a 32-bit displacement following the ModR/M byte, to
|
|
be added to the index.
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
|
|
|
|
Table 17-4. 32-Bit Addressing Forms with the SIB Byte
|
|
|
|
|
|
r32 EAX ECX EDX EBX ESP [*]
|
|
[*] means a disp32 with no base if MOD is 00, [ESP] otherwise. This provides
|
|
the following addressing modes:
|
|
disp32[index] (MOD=00)
|
|
disp8[EBP][index] (MOD=01)
|
|
disp32[EBP][index] (MOD=10) ESI EDI
|
|
Base = 0 1 2 3 4 5 6 7
|
|
Base = 000 001 010 011 100 101 110 111
|
|
|
|
ÚScaled Index
|
|
[*] means a disp32 with no base if MOD is 00, [ESP] otherwise. This provides
|
|
the following addressing modes:
|
|
disp32[index] (MOD=00)
|
|
disp8[EBP][index] (MOD=01)
|
|
disp32[EBP][index] (MOD=10)¿ÚSS Index¿ ÚÄÄÄÄÄÄÄÄModR/M Values in HexadecimalÄÄÄÄÄÄÄÄ¿
|
|
|
|
[EAX] 000 00 01 02 03 04 05 06 07
|
|
[ECX] 001 08 09 0A 0B 0C 0D 0E 0F
|
|
[EDX] 010 10 11 12 13 14 15 16 17
|
|
[EBX] 011 18 19 1A 1B 1C 1D 1E 1F
|
|
none 00 100 20 21 22 23 24 25 26 27
|
|
[EBP] 101 28 29 2A 2B 2C 2D 2E 2F
|
|
[ESI] 110 30 31 32 33 34 35 36 37
|
|
[EDI] 111 38 39 3A 3B 3C 3D 3E 3F
|
|
|
|
[EAX*2] 000 40 41 42 43 44 45 46 47
|
|
[ECX*2] 001 48 49 4A 4B 4C 4D 4E 4F
|
|
[ECX*2] 010 50 51 52 53 54 55 56 57
|
|
[EBX*2] 011 58 59 5A 5B 5C 5D 5E 5F
|
|
none 01 100 60 61 62 63 64 65 66 67
|
|
[EBP*2] 101 68 69 6A 6B 6C 6D 6E 6F
|
|
[ESI*2] 110 70 71 72 73 74 75 76 77
|
|
[EDI*2] 111 78 79 7A 7B 7C 7D 7E 7F
|
|
|
|
[EAX*4] 000 80 81 82 83 84 85 86 87
|
|
[ECX*4] 001 88 89 8A 8B 8C 8D 8E 8F
|
|
[EDX*4] 010 90 91 92 93 94 95 96 97
|
|
[EBX*4] 011 98 89 9A 9B 9C 9D 9E 9F
|
|
none 10 100 A0 A1 A2 A3 A4 A5 A6 A7
|
|
[EBP*4] 101 A8 A9 AA AB AC AD AE AF
|
|
[ESI*4] 110 B0 B1 B2 B3 B4 B5 B6 B7
|
|
[EDI*4] 111 B8 B9 BA BB BC BD BE BF
|
|
|
|
[EAX*8] 000 C0 C1 C2 C3 C4 C5 C6 C7
|
|
[ECX*8] 001 C8 C9 CA CB CC CD CE CF
|
|
[EDX*8] 010 D0 D1 D2 D3 D4 D5 D6 D7
|
|
[EBX*8] 011 D8 D9 DA DB DC DD DE DF
|
|
none 11 100 E0 E1 E2 E3 E4 E5 E6 E7
|
|
[EBP*8] 101 E8 E9 EA EB EC ED EE EF
|
|
[ESI*8] 110 F0 F1 F2 F3 F4 F5 F6 F7
|
|
[EDI*8] 111 F8 F9 FA FB FC FD FE FF
|
|
|
|
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
NOTES:
|
|
[*] means a disp32 with no base if MOD is 00, [ESP] otherwise. This
|
|
provides the following addressing modes:
|
|
disp32[index] (MOD=00)
|
|
disp8[EBP][index] (MOD=01)
|
|
disp32[EBP][index] (MOD=10)
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
|
|
|
|
17.2.2 How to Read the Instruction Set Pages
|
|
|
|
The following is an example of the format used for each 80386 instruction
|
|
description in this chapter:
|
|
|
|
CMC ÄÄ Complement Carry Flag
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
F5 CMC 2 Complement carry flag
|
|
|
|
The above table is followed by paragraphs labelled "Operation,"
|
|
"Description," "Flags Affected," "Protected Mode Exceptions," "Real
|
|
Address Mode Exceptions," and, optionally, "Notes." The following sections
|
|
explain the notational conventions and abbreviations used in these
|
|
paragraphs of the instruction descriptions.
|
|
|
|
|
|
17.2.2.1 Opcode
|
|
|
|
The "Opcode" column gives the complete object code produced for each form
|
|
of the instruction. When possible, the codes are given as hexadecimal bytes,
|
|
in the same order in which they appear in memory. Definitions of entries
|
|
other than hexadecimal bytes are as follows:
|
|
|
|
/digit: (digit is between 0 and 7) indicates that the ModR/M byte of the
|
|
instruction uses only the r/m (register or memory) operand. The reg field
|
|
contains the digit that provides an extension to the instruction's opcode.
|
|
|
|
/r: indicates that the ModR/M byte of the instruction contains both a
|
|
register operand and an r/m operand.
|
|
|
|
cb, cw, cd, cp: a 1-byte (cb), 2-byte (cw), 4-byte (cd) or 6-byte (cp)
|
|
value following the opcode that is used to specify a code offset and
|
|
possibly a new value for the code segment register.
|
|
|
|
ib, iw, id: a 1-byte (ib), 2-byte (iw), or 4-byte (id) immediate operand to
|
|
the instruction that follows the opcode, ModR/M bytes or scale-indexing
|
|
bytes. The opcode determines if the operand is a signed value. All words and
|
|
doublewords are given with the low-order byte first.
|
|
|
|
+rb, +rw, +rd: a register code, from 0 through 7, added to the hexadecimal
|
|
byte given at the left of the plus sign to form a single opcode byte. The
|
|
codes areÄÄ
|
|
|
|
rb rw rd
|
|
AL = 0 AX = 0 EAX = 0
|
|
CL = 1 CX = 1 ECX = 1
|
|
DL = 2 DX = 2 EDX = 2
|
|
BL = 3 BX = 3 EBX = 3
|
|
AH = 4 SP = 4 ESP = 4
|
|
CH = 5 BP = 5 EBP = 5
|
|
DH = 6 SI = 6 ESI = 6
|
|
BH = 7 DI = 7 EDI = 7
|
|
|
|
|
|
17.2.2.2 Instruction
|
|
|
|
The "Instruction" column gives the syntax of the instruction statement as
|
|
it would appear in an ASM386 program. The following is a list of the symbols
|
|
used to represent operands in the instruction statements:
|
|
|
|
rel8: a relative address in the range from 128 bytes before the end of the
|
|
instruction to 127 bytes after the end of the instruction.
|
|
|
|
rel16, rel32: a relative address within the same code segment as the
|
|
instruction assembled. rel16 applies to instructions with an operand-size
|
|
attribute of 16 bits; rel32 applies to instructions with an operand-size
|
|
attribute of 32 bits.
|
|
|
|
ptr16:16, ptr16:32: a FAR pointer, typically in a code segment different
|
|
from that of the instruction. The notation 16:16 indicates that the value of
|
|
the pointer has two parts. The value to the right of the colon is a 16-bit
|
|
selector or value destined for the code segment register. The value to the
|
|
left corresponds to the offset within the destination segment. ptr16:16 is
|
|
used when the instruction's operand-size attribute is 16 bits; ptr16:32 is
|
|
used with the 32-bit attribute.
|
|
|
|
r8: one of the byte registers AL, CL, DL, BL, AH, CH, DH, or BH.
|
|
|
|
r16: one of the word registers AX, CX, DX, BX, SP, BP, SI, or DI.
|
|
|
|
r32: one of the doubleword registers EAX, ECX, EDX, EBX, ESP, EBP, ESI, or
|
|
EDI.
|
|
|
|
imm8: an immediate byte value. imm8 is a signed number between -128 and
|
|
+127 inclusive. For instructions in which imm8 is combined with a word or
|
|
doubleword operand, the immediate value is sign-extended to form a word or
|
|
doubleword. The upper byte of the word is filled with the topmost bit of the
|
|
immediate value.
|
|
|
|
imm16: an immediate word value used for instructions whose operand-size
|
|
attribute is 16 bits. This is a number between -32768 and +32767 inclusive.
|
|
|
|
imm32: an immediate doubleword value used for instructions whose
|
|
operand-size attribute is 32-bits. It allows the use of a number between
|
|
+2147483647 and -2147483648.
|
|
|
|
r/m8: a one-byte operand that is either the contents of a byte register
|
|
(AL, BL, CL, DL, AH, BH, CH, DH), or a byte from memory.
|
|
|
|
r/m16: a word register or memory operand used for instructions whose
|
|
operand-size attribute is 16 bits. The word registers are: AX, BX, CX, DX,
|
|
SP, BP, SI, DI. The contents of memory are found at the address provided by
|
|
the effective address computation.
|
|
|
|
r/m32: a doubleword register or memory operand used for instructions whose
|
|
operand-size attribute is 32-bits. The doubleword registers are: EAX, EBX,
|
|
ECX, EDX, ESP, EBP, ESI, EDI. The contents of memory are found at the
|
|
address provided by the effective address computation.
|
|
|
|
m8: a memory byte addressed by DS:SI or ES:DI (used only by string
|
|
instructions).
|
|
|
|
m16: a memory word addressed by DS:SI or ES:DI (used only by string
|
|
instructions).
|
|
|
|
m32: a memory doubleword addressed by DS:SI or ES:DI (used only by string
|
|
instructions).
|
|
|
|
m16:16, M16:32: a memory operand containing a far pointer composed of two
|
|
numbers. The number to the left of the colon corresponds to the pointer's
|
|
segment selector. The number to the right corresponds to its offset.
|
|
|
|
m16 & 32, m16 & 16, m32 & 32: a memory operand consisting of data item pairs
|
|
whose sizes are indicated on the left and the right side of the ampersand.
|
|
All memory addressing modes are allowed. m16 & 16 and m32 & 32 operands are
|
|
used by the BOUND instruction to provide an operand containing an upper and
|
|
lower bounds for array indices. m16 & 32 is used by LIDT and LGDT to
|
|
provide a word with which to load the limit field, and a doubleword with
|
|
which to load the base field of the corresponding Global and Interrupt
|
|
Descriptor Table Registers.
|
|
|
|
moffs8, moffs16, moffs32: (memory offset) a simple memory variable of type
|
|
BYTE, WORD, or DWORD used by some variants of the MOV instruction. The
|
|
actual address is given by a simple offset relative to the segment base. No
|
|
ModR/M byte is used in the instruction. The number shown with moffs
|
|
indicates its size, which is determined by the address-size attribute of the
|
|
instruction.
|
|
|
|
Sreg: a segment register. The segment register bit assignments are ES=0,
|
|
CS=1, SS=2, DS=3, FS=4, and GS=5.
|
|
|
|
|
|
17.2.2.3 Clocks
|
|
|
|
The "Clocks" column gives the number of clock cycles the instruction takes
|
|
to execute. The clock count calculations makes the following assumptions:
|
|
|
|
þ The instruction has been prefetched and decoded and is ready for
|
|
execution.
|
|
|
|
þ Bus cycles do not require wait states.
|
|
|
|
þ There are no local bus HOLD requests delaying processor access to the
|
|
bus.
|
|
|
|
þ No exceptions are detected during instruction execution.
|
|
|
|
þ Memory operands are aligned.
|
|
|
|
Clock counts for instructions that have an r/m (register or memory) operand
|
|
are separated by a slash. The count to the left is used for a register
|
|
operand; the count to the right is used for a memory operand.
|
|
|
|
The following symbols are used in the clock count specifications:
|
|
|
|
þ n, which represents a number of repetitions.
|
|
|
|
þ m, which represents the number of components in the next instruction
|
|
executed, where the entire displacement (if any) counts as one
|
|
component, the entire immediate data (if any) counts as one component,
|
|
and every other byte of the instruction and prefix(es) each counts as
|
|
one component.
|
|
|
|
þ pm=, a clock count that applies when the instruction executes in
|
|
Protected Mode. pm= is not given when the clock counts are the same for
|
|
Protected and Real Address Modes.
|
|
|
|
When an exception occurs during the execution of an instruction and the
|
|
exception handler is in another task, the instruction execution time is
|
|
increased by the number of clocks to effect a task switch. This parameter
|
|
depends on several factors:
|
|
|
|
þ The type of TSS used to represent the current task (386 TSS or 286
|
|
TSS).
|
|
|
|
þ The type of TSS used to represent the new task.
|
|
|
|
þ Whether the current task is in V86 mode.
|
|
|
|
þ Whether the new task is in V86 mode.
|
|
|
|
Table 17-5 summarizes the task switch times for exceptions.
|
|
|
|
|
|
Table 17-5. Task Switch Times for Exceptions
|
|
|
|
New Task
|
|
|
|
Old 386 TSS 286 TSS
|
|
Task VM = 0
|
|
|
|
386 VM = 0 309 282
|
|
TSS
|
|
|
|
386 VM = 1 314 231
|
|
TSS
|
|
|
|
286 307 282
|
|
TSS
|
|
|
|
|
|
17.2.2.4 Description
|
|
|
|
The "Description" column following the "Clocks" column briefly explains the
|
|
various forms of the instruction. The "Operation" and "Description" sections
|
|
contain more details of the instruction's operation.
|
|
|
|
|
|
17.2.2.5 Operation
|
|
|
|
The "Operation" section contains an algorithmic description of the
|
|
instruction which uses a notation similar to the Algol or Pascal language.
|
|
The algorithms are composed of the following elements:
|
|
|
|
Comments are enclosed within the symbol pairs "(*" and "*)".
|
|
|
|
Compound statements are enclosed between the keywords of the "if" statement
|
|
(IF, THEN, ELSE, FI) or of the "do" statement (DO, OD), or of the "case"
|
|
statement (CASE ... OF, ESAC).
|
|
|
|
A register name implies the contents of the register. A register name
|
|
enclosed in brackets implies the contents of the location whose address is
|
|
contained in that register. For example, ES:[DI] indicates the contents of
|
|
the location whose ES segment relative address is in register DI. [SI]
|
|
indicates the contents of the address contained in register SI relative to
|
|
SI's default segment (DS) or overridden segment.
|
|
|
|
Brackets also used for memory operands, where they mean that the contents
|
|
of the memory location is a segment-relative offset. For example, [SRC]
|
|
indicates that the contents of the source operand is a segment-relative
|
|
offset.
|
|
|
|
A B; indicates that the value of B is assigned to A.
|
|
|
|
The symbols =, <>, ò, and ó are relational operators used to compare two
|
|
values, meaning equal, not equal, greater or equal, less or equal,
|
|
respectively. A relational expression such as A = B is TRUE if the value of
|
|
A is equal to B; otherwise it is FALSE.
|
|
|
|
The following identifiers are used in the algorithmic descriptions:
|
|
|
|
þ OperandSize represents the operand-size attribute of the instruction,
|
|
which is either 16 or 32 bits. AddressSize represents the address-size
|
|
attribute, which is either 16 or 32 bits. For example,
|
|
|
|
IF instruction = CMPSW
|
|
THEN OperandSize 16;
|
|
ELSE
|
|
IF instruction = CMPSD
|
|
THEN OperandSize 32;
|
|
FI;
|
|
FI;
|
|
|
|
indicates that the operand-size attribute depends on the form of the CMPS
|
|
instruction used. Refer to the explanation of address-size and operand-size
|
|
attributes at the beginning of this chapter for general guidelines on how
|
|
these attributes are determined.
|
|
|
|
þ StackAddrSize represents the stack address-size attribute associated
|
|
with the instruction, which has a value of 16 or 32 bits, as explained
|
|
earlier in the chapter.
|
|
|
|
þ SRC represents the source operand. When there are two operands, SRC is
|
|
the one on the right.
|
|
|
|
þ DEST represents the destination operand. When there are two operands,
|
|
DEST is the one on the left.
|
|
|
|
þ LeftSRC, RightSRC distinguishes between two operands when both are
|
|
source operands.
|
|
|
|
þ eSP represents either the SP register or the ESP register depending on
|
|
the setting of the B-bit for the current stack segment.
|
|
|
|
The following functions are used in the algorithmic descriptions:
|
|
|
|
þ Truncate to 16 bits(value) reduces the size of the value to fit in 16
|
|
bits by discarding the uppermost bits as needed.
|
|
|
|
þ Addr(operand) returns the effective address of the operand (the result
|
|
of the effective address calculation prior to adding the segment base).
|
|
|
|
þ ZeroExtend(value) returns a value zero-extended to the operand-size
|
|
attribute of the instruction. For example, if OperandSize = 32,
|
|
ZeroExtend of a byte value of -10 converts the byte from F6H to
|
|
doubleword with hexadecimal value 000000F6H. If the value passed to
|
|
ZeroExtend and the operand-size attribute are the same size,
|
|
ZeroExtend returns the value unaltered.
|
|
|
|
þ SignExtend(value) returns a value sign-extended to the operand-size
|
|
attribute of the instruction. For example, if OperandSize = 32,
|
|
SignExtend of a byte containing the value -10 converts the byte from
|
|
F6H to a doubleword with hexadecimal value FFFFFFF6H. If the value
|
|
passed to SignExtend and the operand-size attribute are the same size,
|
|
SignExtend returns the value unaltered.
|
|
|
|
þ Push(value) pushes a value onto the stack. The number of bytes pushed
|
|
is determined by the operand-size attribute of the instruction. The
|
|
action of Push is as follows:
|
|
|
|
IF StackAddrSize = 16
|
|
THEN
|
|
IF OperandSize = 16
|
|
THEN
|
|
SP SP - 2;
|
|
SS:[SP] value; (* 2 bytes assigned starting at
|
|
byte address in SP *)
|
|
ELSE (* OperandSize = 32 *)
|
|
SP SP - 4;
|
|
SS:[SP] value; (* 4 bytes assigned starting at
|
|
byte address in SP *)
|
|
FI;
|
|
ELSE (* StackAddrSize = 32 *)
|
|
IF OperandSize = 16
|
|
THEN
|
|
ESP ESP - 2;
|
|
SS:[ESP] value; (* 2 bytes assigned starting at
|
|
byte address in ESP*)
|
|
ELSE (* OperandSize = 32 *)
|
|
ESP ESP - 4;
|
|
SS:[ESP] value; (* 4 bytes assigned starting at
|
|
byte address in ESP*)
|
|
FI;
|
|
FI;
|
|
|
|
þ Pop(value) removes the value from the top of the stack and returns it.
|
|
The statement EAX Pop( ); assigns to EAX the 32-bit value that Pop
|
|
took from the top of the stack. Pop will return either a word or a
|
|
doubleword depending on the operand-size attribute. The action of Pop
|
|
is as follows:
|
|
|
|
IF StackAddrSize = 16
|
|
THEN
|
|
IF OperandSize = 16
|
|
THEN
|
|
ret val SS:[SP]; (* 2-byte value *)
|
|
SP SP + 2;
|
|
ELSE (* OperandSize = 32 *)
|
|
ret val SS:[SP]; (* 4-byte value *)
|
|
SP SP + 4;
|
|
FI;
|
|
ELSE (* StackAddrSize = 32 *)
|
|
IF OperandSize = 16
|
|
THEN
|
|
ret val SS:[ESP]; (* 2 bytes value *)
|
|
ESP ESP + 2;
|
|
ELSE (* OperandSize = 32 *)
|
|
ret val SS:[ESP]; (* 4 bytes value *)
|
|
ESP ESP + 4;
|
|
FI;
|
|
FI;
|
|
RETURN(ret val); (*returns a word or doubleword*)
|
|
|
|
þ Bit[BitBase, BitOffset] returns the address of a bit within a bit
|
|
string, which is a sequence of bits in memory or a register. Bits are
|
|
numbered from low-order to high-order within registers and within
|
|
memory bytes. In memory, the two bytes of a word are stored with the
|
|
low-order byte at the lower address.
|
|
|
|
If the base operand is a register, the offset can be in the range 0..31.
|
|
This offset addresses a bit within the indicated register. An example,
|
|
"BIT[EAX, 21]," is illustrated in Figure 17-3.
|
|
|
|
If BitBase is a memory address, BitOffset can range from -2 gigabits to 2
|
|
gigabits. The addressed bit is numbered (Offset MOD 8) within the byte at
|
|
address (BitBase + (BitOffset DIV 8)), where DIV is signed division with
|
|
rounding towards negative infinity, and MOD returns a positive number.
|
|
This is illustrated in Figure 17-4.
|
|
|
|
þ I-O-Permission(I-O-Address, width) returns TRUE or FALSE depending on
|
|
the I/O permission bitmap and other factors. This function is defined as
|
|
follows:
|
|
|
|
IF TSS type is 286 THEN RETURN FALSE; FI;
|
|
Ptr [TSS + 66]; (* fetch bitmap pointer *)
|
|
BitStringAddr SHR (I-O-Address, 3) + Ptr;
|
|
MaskShift I-O-Address AND 7;
|
|
CASE width OF:
|
|
BYTE: nBitMask 1;
|
|
WORD: nBitMask 3;
|
|
DWORD: nBitMask 15;
|
|
ESAC;
|
|
mask SHL (nBitMask, MaskShift);
|
|
CheckString [BitStringAddr] AND mask;
|
|
IF CheckString = 0
|
|
THEN RETURN (TRUE);
|
|
ELSE RETURN (FALSE);
|
|
FI;
|
|
|
|
þ Switch-Tasks is the task switching function described in Chapter 7.
|
|
|
|
|
|
17.2.2.6 Description
|
|
|
|
The "Description" section contains further explanation of the instruction's
|
|
operation.
|
|
|
|
|
|
Figure 17-3. Bit Offset for BIT[EAX, 21]
|
|
|
|
31 21 0
|
|
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
|
º º º º
|
|
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
|
|
|
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄBITOFFSET = 21ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
|
|
|
|
|
Figure 17-4. Memory Bit Indexing
|
|
|
|
BIT INDEXING (POSITIVE OFFSET)
|
|
|
|
7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
|
ÉÍÍÍÍÑÍÑÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
|
º ³ ³ ³ ³ º
|
|
ÈÍÍÍÍÏÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
|
³ BITBASE + 1 ³ BITBASE ³ BITBASE - 1 ³
|
|
³
|
|
ÀÄÄÄÄÄÄÄÄOFFSET = 13ÄÄÄÄÄÄÄÙ
|
|
|
|
BIT INDEXING (NEGATIVE OFFSET)
|
|
|
|
7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
|
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÑÍÑÍÍÍÍÍÍÍÍÍÍ»
|
|
º ³ ³ ³ ³ º
|
|
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÏÍÏÍÍÍÍÍÍÍÍÍͼ
|
|
³ BITBASE ³ BITBASE - 1 ³ BITBASE - 2 ³
|
|
³
|
|
ÀÄÄÄÄÄOFFSET = -11ÄÄÄÙ
|
|
|
|
|
|
17.2.2.7 Flags Affected
|
|
|
|
The "Flags Affected" section lists the flags that are affected by the
|
|
instruction, as follows:
|
|
|
|
þ If a flag is always cleared or always set by the instruction, the
|
|
value is given (0 or 1) after the flag name. Arithmetic and logical
|
|
instructions usually assign values to the status flags in the uniform
|
|
manner described in Appendix C. Nonconventional assignments are
|
|
described in the "Operation" section.
|
|
|
|
þ The values of flags listed as "undefined" may be changed by the
|
|
instruction in an indeterminate manner.
|
|
|
|
All flags not listed are unchanged by the instruction.
|
|
|
|
|
|
17.2.2.8 Protected Mode Exceptions
|
|
|
|
This section lists the exceptions that can occur when the instruction is
|
|
executed in 80386 Protected Mode. The exception names are a pound sign (#)
|
|
followed by two letters and an optional error code in parentheses. For
|
|
example, #GP(0) denotes a general protection exception with an error code of
|
|
0. Table 17-6 associates each two-letter name with the corresponding
|
|
interrupt number.
|
|
|
|
Chapter 9 describes the exceptions and the 80386 state upon entry to the
|
|
exception.
|
|
|
|
Application programmers should consult the documentation provided with
|
|
their operating systems to determine the actions taken when exceptions
|
|
occur.
|
|
|
|
|
|
Table 17-6. 80386 Exceptions
|
|
|
|
Mnemonic Interrupt Description
|
|
|
|
#UD 6 Invalid opcode
|
|
#NM 7 Coprocessor not available
|
|
#DF 8 Double fault
|
|
#TS 10 Invalid TSS
|
|
#NP 11 Segment or gate not present
|
|
#SS 12 Stack fault
|
|
#GP 13 General protection fault
|
|
#PF 14 Page fault
|
|
#MF 16 Math (coprocessor) fault
|
|
|
|
|
|
17.2.2.9 Real Address Mode Exceptions
|
|
|
|
Because less error checking is performed by the 80386 in Real Address Mode,
|
|
this mode has fewer exception conditions. Refer to Chapter 14 for further
|
|
information on these exceptions.
|
|
|
|
|
|
17.2.2.10 Virtual-8086 Mode Exceptions
|
|
|
|
Virtual 8086 tasks provide the ability to simulate Virtual 8086 machines.
|
|
Virtual 8086 Mode exceptions are similar to those for the 8086 processor,
|
|
but there are some differences. Refer to Chapter 15 for details.
|
|
|
|
|
|
AAA ÄÄ ASCII Adjust after Addition
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
37 AAA 4 ASCII adjust AL after addition
|
|
|
|
|
|
Operation
|
|
|
|
IF ((AL AND 0FH) > 9) OR (AF = 1)
|
|
THEN
|
|
AL (AL + 6) AND 0FH;
|
|
AH AH + 1;
|
|
AF 1;
|
|
CF 1;
|
|
ELSE
|
|
CF 0;
|
|
AF 0;
|
|
FI;
|
|
|
|
Description
|
|
|
|
Execute AAA only following an ADD instruction that leaves a byte result
|
|
in the AL register. The lower nibbles of the operands of the ADD instruction
|
|
should be in the range 0 through 9 (BCD digits). In this case, AAA adjusts
|
|
AL to contain the correct decimal digit result. If the addition produced a
|
|
decimal carry, the AH register is incremented, and the carry and auxiliary
|
|
carry flags are set to 1. If there was no decimal carry, the carry and
|
|
auxiliary flags are set to 0 and AH is unchanged. In either case, AL is left
|
|
with its top nibble set to 0. To convert AL to an ASCII result, follow the
|
|
AAA instruction with OR AL, 30H.
|
|
|
|
Flags Affected
|
|
|
|
AF and CF as described above; OF, SF, ZF, and PF are undefined
|
|
|
|
Protected Mode Exceptions
|
|
|
|
None
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
None
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
None
|
|
|
|
|
|
AAD ÄÄ ASCII Adjust AX before Division
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
D5 0A AAD 19 ASCII adjust AX before division
|
|
|
|
|
|
Operation
|
|
|
|
AL AH * 10 + AL;
|
|
AH 0;
|
|
|
|
Description
|
|
|
|
AAD is used to prepare two unpacked BCD digits (the least-significant
|
|
digit in AL, the most-significant digit in AH) for a division operation that
|
|
will yield an unpacked result. This is accomplished by setting AL to
|
|
AL + (10 * AH), and then setting AH to 0. AX is then equal to the binary
|
|
equivalent of the original unpacked two-digit number.
|
|
|
|
Flags Affected
|
|
|
|
SF, ZF, and PF as described in Appendix C; OF, AF, and CF are undefined
|
|
|
|
Protected Mode Exceptions
|
|
|
|
None
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
None
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
None
|
|
|
|
|
|
AAM ÄÄ ASCII Adjust AX after Multiply
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
D4 0A AAM 17 ASCII adjust AX after multiply
|
|
|
|
|
|
Operation
|
|
|
|
AH AL / 10;
|
|
AL AL MOD 10;
|
|
|
|
Description
|
|
|
|
Execute AAM only after executing a MUL instruction between two unpacked
|
|
BCD digits that leaves the result in the AX register. Because the result is
|
|
less than 100, it is contained entirely in the AL register. AAM unpacks the
|
|
AL result by dividing AL by 10, leaving the quotient (most-significant
|
|
digit) in AH and the remainder (least-significant digit) in AL.
|
|
|
|
Flags Affected
|
|
|
|
SF, ZF, and PF as described in Appendix C; OF, AF, and CF are undefined
|
|
|
|
Protected Mode Exceptions
|
|
|
|
None
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
None
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
None
|
|
|
|
|
|
AAS ÄÄ ASCII Adjust AL after Subtraction
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
3F AAS 4 ASCII adjust AL after subtraction
|
|
|
|
|
|
Operation
|
|
|
|
IF (AL AND 0FH) > 9 OR AF = 1
|
|
THEN
|
|
AL AL - 6;
|
|
AL AL AND 0FH;
|
|
AH AH - 1;
|
|
AF 1;
|
|
CF 1;
|
|
ELSE
|
|
CF 0;
|
|
AF 0;
|
|
FI;
|
|
|
|
Description
|
|
|
|
Execute AAS only after a SUB instruction that leaves the byte result in the
|
|
AL register. The lower nibbles of the operands of the SUB instruction must
|
|
have been in the range 0 through 9 (BCD digits). In this case, AAS adjusts
|
|
AL so it contains the correct decimal digit result. If the subtraction
|
|
produced a decimal carry, the AH register is decremented, and the carry and
|
|
auxiliary carry flags are set to 1. If no decimal carry occurred, the carry
|
|
and auxiliary carry flags are set to 0, and AH is unchanged. In either case,
|
|
AL is left with its top nibble set to 0. To convert AL to an ASCII result,
|
|
follow the AAS with OR AL, 30H.
|
|
|
|
Flags Affected
|
|
|
|
AF and CF as described above; OF, SF, ZF, and PF are undefined
|
|
|
|
Protected Mode Exceptions
|
|
|
|
None
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
None
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
None
|
|
|
|
|
|
ADC ÄÄ Add with Carry
|
|
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
14 ib ADC AL,imm8 2 Add with carry immediate byte to AL
|
|
15 iw ADC AX,imm16 2 Add with carry immediate word to AX
|
|
15 id ADC EAX,imm32 2 Add with carry immediate dword to EAX
|
|
80 /2 ib ADC r/m8,imm8 2/7 Add with carry immediate byte to r/m
|
|
byte
|
|
81 /2 iw ADC r/m16,imm16 2/7 Add with carry immediate word to r/m
|
|
word
|
|
81 /2 id ADC r/m32,imm32 2/7 Add with CF immediate dword to r/m
|
|
dword
|
|
83 /2 ib ADC r/m16,imm8 2/7 Add with CF sign-extended immediate
|
|
byte to r/m word
|
|
83 /2 ib ADC r/m32,imm8 2/7 Add with CF sign-extended immediate
|
|
byte into r/m dword
|
|
10 /r ADC r/m8,r8 2/7 Add with carry byte register to r/m
|
|
byte
|
|
11 /r ADC r/m16,r16 2/7 Add with carry word register to r/m
|
|
word
|
|
11 /r ADC r/m32,r32 2/7 Add with CF dword register to r/m dword
|
|
12 /r ADC r8,r/m8 2/6 Add with carry r/m byte to byte
|
|
register
|
|
13 /r ADC r16,r/m16 2/6 Add with carry r/m word to word
|
|
register
|
|
13 /r ADC r32,r/m32 2/6 Add with CF r/m dword to dword register
|
|
|
|
|
|
Operation
|
|
|
|
DEST DEST + SRC + CF;
|
|
|
|
Description
|
|
|
|
ADC performs an integer addition of the two operands DEST and SRC and the
|
|
carry flag, CF. The result of the addition is assigned to the first operand
|
|
(DEST), and the flags are set accordingly. ADC is usually executed as part
|
|
of a multi-byte or multi-word addition operation. When an immediate byte
|
|
value is added to a word or doubleword operand, the immediate value is first
|
|
sign-extended to the size of the word or doubleword operand.
|
|
|
|
Flags Affected
|
|
|
|
OF, SF, ZF, AF, CF, and PF as described in Appendix C
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
|
|
memory operand effective address in the CS, DS, ES, FS, or GS segments;
|
|
#SS(0) for an illegal address in the SS segment; #PF(fault-code) if page
|
|
fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
|
|
|
|
|
|
ADD ÄÄ Add
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
04 ib ADD AL,imm8 2 Add immediate byte to AL
|
|
05 iw ADD AX,imm16 2 Add immediate word to AX
|
|
05 id ADD EAX,imm32 2 Add immediate dword to EAX
|
|
80 /0 ib ADD r/m8,imm8 2/7 Add immediate byte to r/m byte
|
|
81 /0 iw ADD r/m16,imm16 2/7 Add immediate word to r/m word
|
|
81 /0 id ADD r/m32,imm32 2/7 Add immediate dword to r/m dword
|
|
83 /0 ib ADD r/m16,imm8 2/7 Add sign-extended immediate byte
|
|
to r/m word
|
|
83 /0 ib ADD r/m32,imm8 2/7 Add sign-extended immediate byte
|
|
to r/m dword
|
|
00 /r ADD r/m8,r8 2/7 Add byte register to r/m byte
|
|
01 /r ADD r/m16,r16 2/7 Add word register to r/m word
|
|
01 /r ADD r/m32,r32 2/7 Add dword register to r/m dword
|
|
02 /r ADD r8,r/m8 2/6 Add r/m byte to byte register
|
|
03 /r ADD r16,r/m16 2/6 Add r/m word to word register
|
|
03 /r ADD r32,r/m32 2/6 Add r/m dword to dword register
|
|
|
|
|
|
Operation
|
|
|
|
DEST DEST + SRC;
|
|
|
|
Description
|
|
|
|
ADD performs an integer addition of the two operands (DEST and SRC). The
|
|
result of the addition is assigned to the first operand (DEST), and the
|
|
flags are set accordingly.
|
|
|
|
When an immediate byte is added to a word or doubleword operand, the
|
|
immediate value is sign-extended to the size of the word or doubleword
|
|
operand.
|
|
|
|
Flags Affected
|
|
|
|
OF, SF, ZF, AF, CF, and PF as described in Appendix C
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
|
|
memory operand effective address in the CS, DS, ES, FS, or GS segments;
|
|
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page
|
|
fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
|
|
|
|
|
|
AND ÄÄ Logical AND
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
24 ib AND AL,imm8 2 AND immediate byte to AL
|
|
25 iw AND AX,imm16 2 AND immediate word to AX
|
|
25 id AND EAX,imm32 2 AND immediate dword to EAX
|
|
80 /4 ib AND r/m8,imm8 2/7 AND immediate byte to r/m byte
|
|
81 /4 iw AND r/m16,imm16 2/7 AND immediate word to r/m word
|
|
81 /4 id AND r/m32,imm32 2/7 AND immediate dword to r/m dword
|
|
83 /4 ib AND r/m16,imm8 2/7 AND sign-extended immediate byte
|
|
with r/m word
|
|
83 /4 ib AND r/m32,imm8 2/7 AND sign-extended immediate byte
|
|
with r/m dword
|
|
20 /r AND r/m8,r8 2/7 AND byte register to r/m byte
|
|
21 /r AND r/m16,r16 2/7 AND word register to r/m word
|
|
21 /r AND r/m32,r32 2/7 AND dword register to r/m dword
|
|
22 /r AND r8,r/m8 2/6 AND r/m byte to byte register
|
|
23 /r AND r16,r/m16 2/6 AND r/m word to word register
|
|
23 /r AND r32,r/m32 2/6 AND r/m dword to dword register
|
|
|
|
|
|
Operation
|
|
|
|
DEST DEST AND SRC;
|
|
CF 0;
|
|
OF 0;
|
|
|
|
Description
|
|
|
|
Each bit of the result of the AND instruction is a 1 if both corresponding
|
|
bits of the operands are 1; otherwise, it becomes a 0.
|
|
|
|
Flags Affected
|
|
|
|
CF = 0, OF = 0; PF, SF, and ZF as described in Appendix C
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
|
|
memory operand effective address in the CS, DS, ES, FS, or GS segments;
|
|
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page
|
|
fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
|
|
|
|
|
|
ARPL ÄÄ Adjust RPL Field of Selector
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
63 /r ARPL r/m16,r16 pm=20/21 Adjust RPL of r/m16 to not
|
|
less than RPL of r16
|
|
|
|
|
|
Operation
|
|
|
|
IF RPL bits(0,1) of DEST < RPL bits(0,1) of SRC
|
|
THEN
|
|
ZF 1;
|
|
RPL bits(0,1) of DEST RPL bits(0,1) of SRC;
|
|
ELSE
|
|
ZF 0;
|
|
FI;
|
|
|
|
Description
|
|
|
|
The ARPL instruction has two operands. The first operand is a 16-bit
|
|
memory variable or word register that contains the value of a selector. The
|
|
second operand is a word register. If the RPL field ("requested privilege
|
|
level"ÄÄbottom two bits) of the first operand is less than the RPL field of
|
|
the second operand, the zero flag is set to 1 and the RPL field of the
|
|
first operand is increased to match the second operand. Otherwise, the zero
|
|
flag is set to 0 and no change is made to the first operand.
|
|
|
|
ARPL appears in operating system software, not in application programs. It
|
|
is used to guarantee that a selector parameter to a subroutine does not
|
|
request more privilege than the caller is allowed. The second operand of
|
|
ARPL is normally a register that contains the CS selector value of the
|
|
caller.
|
|
|
|
Flags Affected
|
|
|
|
ZF as described above
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
|
|
memory operand effective address in the CS, DS, ES, FS, or GS segments;
|
|
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page
|
|
fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 6; ARPL is not recognized in Real Address Mode
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
|
|
|
|
|
|
BOUND ÄÄ Check Array Index Against Bounds
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
62 /r BOUND r16,m16&16 10 Check if r16 is within bounds
|
|
(passes test)
|
|
62 /r BOUND r32,m32&32 10 Check if r32 is within bounds
|
|
(passes test)
|
|
|
|
|
|
Operation
|
|
|
|
IF (LeftSRC < [RightSRC] OR LeftSRC > [RightSRC + OperandSize/8])
|
|
(* Under lower bound or over upper bound *)
|
|
THEN Interrupt 5;
|
|
FI;
|
|
|
|
Description
|
|
|
|
BOUND ensures that a signed array index is within the limits specified by a
|
|
block of memory consisting of an upper and a lower bound. Each bound uses
|
|
one word for an operand-size attribute of 16 bits and a doubleword for an
|
|
operand-size attribute of 32 bits. The first operand (a register) must be
|
|
greater than or equal to the first bound in memory (lower bound), and less
|
|
than or equal to the second bound in memory (upper bound). If the register
|
|
is not within bounds, an Interrupt 5 occurs; the return EIP points to the
|
|
BOUND instruction.
|
|
|
|
The bounds limit data structure is usually placed just before the array
|
|
itself, making the limits addressable via a constant offset from the
|
|
beginning of the array.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
Interrupt 5 if the bounds test fails, as described above; #GP(0) for an
|
|
illegal memory operand effective address in the CS, DS, ES, FS, or GS
|
|
segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code)
|
|
for a page fault
|
|
|
|
The second operand must be a memory operand, not a register. If BOUND is
|
|
executed with a ModRM byte representing a register as the second operand,
|
|
#UD occurs.
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 5 if the bounds test fails; Interrupt 13 if any part of the
|
|
operand would lie outside of the effective address space from 0 to 0FFFFH;
|
|
Interrupt 6 if the second operand is a register
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
|
|
|
|
|
|
BSF ÄÄ Bit Scan Forward
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
0F BC BSF r16,r/m16 10+3n Bit scan forward on r/m word
|
|
0F BC BSF r32,r/m32 10+3n Bit scan forward on r/m dword
|
|
|
|
|
|
Notes
|
|
|
|
is the number of leading zero bits.
|
|
|
|
Operation
|
|
|
|
IF r/m = 0
|
|
THEN
|
|
ZF 1;
|
|
register UNDEFINED;
|
|
ELSE
|
|
temp 0;
|
|
ZF 0;
|
|
WHILE BIT[r/m, temp = 0]
|
|
DO
|
|
temp temp + 1;
|
|
register temp;
|
|
OD;
|
|
FI;
|
|
|
|
Description
|
|
|
|
BSF scans the bits in the second word or doubleword operand starting with
|
|
bit 0. The ZF flag is cleared if the bits are all 0; otherwise, the ZF flag
|
|
is set and the destination register is loaded with the bit index of the
|
|
first set bit.
|
|
|
|
Flags Affected
|
|
|
|
ZF as described above
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) for an illegal memory operand effective address in the CS, DS, ES,
|
|
FS, or GS segments; #SS(0) for an illegal address in the SS segment;
|
|
#PF(fault-code) for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
|
|
|
|
|
|
BSR ÄÄ Bit Scan Reverse
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
0F BD BSR r16,r/m16 10+3n Bit scan reverse on r/m word
|
|
0F BD BSR r32,r/m32 10+3n Bit scan reverse on r/m dword
|
|
|
|
|
|
Operation
|
|
|
|
IF r/m = 0
|
|
THEN
|
|
ZF 1;
|
|
register UNDEFINED;
|
|
ELSE
|
|
temp OperandSize - 1;
|
|
ZF 0;
|
|
WHILE BIT[r/m, temp] = 0
|
|
DO
|
|
temp temp - 1;
|
|
register temp;
|
|
OD;
|
|
FI;
|
|
|
|
Description
|
|
|
|
BSR scans the bits in the second word or doubleword operand from the most
|
|
significant bit to the least significant bit. The ZF flag is cleared if the
|
|
bits are all 0; otherwise, ZF is set and the destination register is loaded
|
|
with the bit index of the first set bit found when scanning in the reverse
|
|
direction.
|
|
|
|
Flags Affected
|
|
|
|
ZF as described above
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
|
|
memory operand effective address in the CS, DS, ES, FS, or GS segments;
|
|
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page
|
|
fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
|
|
|
|
|
|
BT ÄÄ Bit Test
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
0F A3 BT r/m16,r16 3/12 Save bit in carry flag
|
|
0F A3 BT r/m32,r32 3/12 Save bit in carry flag
|
|
0F BA /4 ib BT r/m16,imm8 3/6 Save bit in carry flag
|
|
0F BA /4 ib BT r/m32,imm8 3/6 Save bit in carry flag
|
|
|
|
|
|
Operation
|
|
|
|
CF BIT[LeftSRC, RightSRC];
|
|
|
|
Description
|
|
|
|
BT saves the value of the bit indicated by the base (first operand) and the
|
|
bit offset (second operand) into the carry flag.
|
|
|
|
Flags Affected
|
|
|
|
CF as described above
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) for an illegal memory operand effective address in the CS, DS, ES,
|
|
FS, or GS segments; #SS(0) for an illegal address in the SS segment;
|
|
#PF(fault-code) for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
|
|
|
|
Notes
|
|
|
|
The index of the selected bit can be given by the immediate constant in the
|
|
instruction or by a value in a general register. Only an 8-bit immediate
|
|
value is used in the instruction. This operand is taken modulo 32, so the
|
|
range of immediate bit offsets is 0..31. This allows any bit within a
|
|
register to be selected. For memory bit strings, this immediate field gives
|
|
only the bit offset within a word or doubleword. Immediate bit offsets
|
|
larger than 31 are supported by using the immediate bit offset field in
|
|
combination with the displacement field of the memory operand. The low-order
|
|
3 to 5 bits of the immediate bit offset are stored in the immediate bit
|
|
offset field, and the high-order 27 to 29 bits are shifted and combined with
|
|
the byte displacement in the addressing mode.
|
|
|
|
When accessing a bit in memory, the 80386 may access four bytes starting
|
|
from the memory address given by:
|
|
|
|
Effective Address + (4 * (BitOffset DIV 32))
|
|
|
|
for a 32-bit operand size, or two bytes starting from the memory address
|
|
given by:
|
|
|
|
Effective Address + (2 * (BitOffset DIV 16))
|
|
|
|
for a 16-bit operand size. It may do so even when only a single byte needs
|
|
to be accessed in order to reach the given bit. You must therefore avoid
|
|
referencing areas of memory close to address space holes. In particular,
|
|
avoid references to memory-mapped I/O registers. Instead, use the MOV
|
|
instructions to load from or store to these addresses, and use the register
|
|
form of these instructions to manipulate the data.
|
|
|
|
|
|
BTC ÄÄ Bit Test and Complement
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
0F BB BTC r/m16,r16 6/13 Save bit in carry flag and complement
|
|
0F BB BTC r/m32,r32 6/13 Save bit in carry flag and complement
|
|
0F BA /7 ib BTC r/m16,imm8 6/8 Save bit in carry flag and complement
|
|
0F BA /7 ib BTC r/m32,imm8 6/8 Save bit in carry flag and complement
|
|
|
|
|
|
Operation
|
|
|
|
CF BIT[LeftSRC, RightSRC];
|
|
BIT[LeftSRC, RightSRC] NOT BIT[LeftSRC, RightSRC];
|
|
|
|
Description
|
|
|
|
BTC saves the value of the bit indicated by the base (first operand) and the
|
|
bit offset (second operand) into the carry flag and then complements the
|
|
bit.
|
|
|
|
Flags Affected
|
|
|
|
CF as described above
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
|
|
memory operand effective address in the CS, DS, ES, FS, or GS segments;
|
|
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page
|
|
fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
|
|
|
|
Notes
|
|
|
|
The index of the selected bit can be given by the immediate constant in the
|
|
instruction or by a value in a general register. Only an 8-bit immediate
|
|
value is used in the instruction. This operand is taken modulo 32, so the
|
|
range of immediate bit offsets is 0..31. This allows any bit within a
|
|
register to be selected. For memory bit strings, this immediate field gives
|
|
only the bit offset within a word or doubleword. Immediate bit offsets
|
|
larger than 31 are supported by using the immediate bit offset field in
|
|
combination with the displacement field of the memory operand. The low-order
|
|
3 to 5 bits of the immediate bit offset are stored in the immediate bit
|
|
offset field, and the high-order 27 to 29 bits are shifted and combined with
|
|
the byte displacement in the addressing mode.
|
|
|
|
When accessing a bit in memory, the 80386 may access four bytes starting
|
|
from the memory address given by:
|
|
|
|
Effective Address + (4 * (BitOffset DIV 32))
|
|
|
|
for a 32-bit operand size, or two bytes starting from the memory address
|
|
given by:
|
|
|
|
Effective Address + (2 * (BitOffset DIV 16))
|
|
|
|
for a 16-bit operand size. It may do so even when only a single byte needs
|
|
to be accessed in order to reach the given bit. You must therefore avoid
|
|
referencing areas of memory close to address space holes. In particular,
|
|
avoid references to memory-mapped I/O registers. Instead, use the MOV
|
|
instructions to load from or store to these addresses, and use the register
|
|
form of these instructions to manipulate the data.
|
|
|
|
|
|
BTR ÄÄ Bit Test and Reset
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
0F B3 BTR r/m16,r16 6/13 Save bit in carry flag and reset
|
|
0F B3 BTR r/m32,r32 6/13 Save bit in carry flag and reset
|
|
0F BA /6 ib BTR r/m16,imm8 6/8 Save bit in carry flag and reset
|
|
0F BA /6 ib BTR r/m32,imm8 6/8 Save bit in carry flag and reset
|
|
|
|
|
|
Operation
|
|
|
|
CF BIT[LeftSRC, RightSRC];
|
|
BIT[LeftSRC, RightSRC] 0;
|
|
|
|
Description
|
|
|
|
BTR saves the value of the bit indicated by the base (first operand) and the
|
|
bit offset (second operand) into the carry flag and then stores 0 in the
|
|
bit.
|
|
|
|
Flags Affected
|
|
|
|
CF as described above
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
|
|
memory operand effective address in the CS, DS, ES, FS, or GS segments;
|
|
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page
|
|
fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
|
|
|
|
Notes
|
|
|
|
The index of the selected bit can be given by the immediate constant in the
|
|
instruction or by a value in a general register. Only an 8-bit immediate
|
|
value is used in the instruction. This operand is taken modulo 32, so the
|
|
range of immediate bit offsets is 0..31. This allows any bit within a
|
|
register to be selected. For memory bit strings, this immediate field gives
|
|
only the bit offset within a word or doubleword. Immediate bit offsets
|
|
larger than 31 (or 15) are supported by using the immediate bit offset field
|
|
in combination with the displacement field of the memory operand. The
|
|
low-order 3 to 5 bits of the immediate bit offset are stored in the
|
|
immediate bit offset field, and the high-order 27 to 29 bits are shifted and
|
|
combined with the byte displacement in the addressing mode.
|
|
|
|
When accessing a bit in memory, the 80386 may access four bytes starting
|
|
from the memory address given by:
|
|
|
|
Effective Address + 4 * (BitOffset DIV 32)
|
|
|
|
for a 32-bit operand size, or two bytes starting from the memory address
|
|
given by:
|
|
|
|
Effective Address + 2 * (BitOffset DIV 16)
|
|
|
|
for a 16-bit operand size. It may do so even when only a single byte needs
|
|
to be accessed in order to reach the given bit. You must therefore avoid
|
|
referencing areas of memory close to address space holes. In particular,
|
|
avoid references to memory-mapped I/O registers. Instead, use the MOV
|
|
instructions to load from or store to these addresses, and use the register
|
|
form of these instructions to manipulate the data.
|
|
|
|
|
|
BTS ÄÄ Bit Test and Set
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
0F AB BTS r/m16,r16 6/13 Save bit in carry flag and set
|
|
0F AB BTS r/m32,r32 6/13 Save bit in carry flag and set
|
|
0F BA /5 ib BTS r/m16,imm8 6/8 Save bit in carry flag and set
|
|
0F BA /5 ib BTS r/m32,imm8 6/8 Save bit in carry flag and set
|
|
|
|
|
|
Operation
|
|
|
|
CF BIT[LeftSRC, RightSRC];
|
|
BIT[LeftSRC, RightSRC] 1;
|
|
|
|
Description
|
|
|
|
BTS saves the value of the bit indicated by the base (first operand) and the
|
|
bit offset (second operand) into the carry flag and then stores 1 in the
|
|
bit.
|
|
|
|
Flags Affected
|
|
|
|
CF as described above
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
|
|
memory operand effective address in the CS, DS, ES, FS, or GS segments;
|
|
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page
|
|
fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
|
|
|
|
Notes
|
|
|
|
The index of the selected bit can be given by the immediate constant in the
|
|
instruction or by a value in a general register. Only an 8-bit immediate
|
|
value is used in the instruction. This operand is taken modulo 32, so the
|
|
range of immediate bit offsets is 0..31. This allows any bit within a
|
|
register to be selected. For memory bit strings, this immediate field gives
|
|
only the bit offset within a word or doubleword. Immediate bit offsets
|
|
larger than 31 are supported by using the immediate bit offset field in
|
|
combination with the displacement field of the memory operand. The
|
|
low-order 3 to 5 bits of the immediate bit offset are stored in the
|
|
immediate bit offset field, and the high order 27 to 29 bits are shifted and
|
|
combined with the byte displacement in the addressing mode.
|
|
|
|
When accessing a bit in memory, the processor may access four bytes starting
|
|
from the memory address given by:
|
|
|
|
Effective Address + (4 * (BitOffset DIV 32))
|
|
|
|
for a 32-bit operand size, or two bytes starting from the memory address
|
|
given by:
|
|
|
|
Effective Address + (2 * (BitOffset DIV 16))
|
|
|
|
for a 16-bit operand size. It may do this even when only a single byte needs
|
|
to be accessed in order to get at the given bit. Thus the programmer must be
|
|
careful to avoid referencing areas of memory close to address space holes.
|
|
In particular, avoid references to memory-mapped I/O registers. Instead, use
|
|
the MOV instructions to load from or store to these addresses, and use the
|
|
register form of these instructions to manipulate the data.
|
|
|
|
|
|
CALL ÄÄ Call Procedure
|
|
|
|
|
|
Opcode Instruction Clocks
|
|
Values of ts are given by the following table:
|
|
|
|
New Task
|
|
386 TSS 386 TSS 286 TSS
|
|
Old VM = 0 VM = 1
|
|
Task Via Task Gate?
|
|
|
|
N Y N Y N Y
|
|
|
|
386 300 309 217 226 273 282
|
|
TSS VM=0
|
|
|
|
286 298 307 217 226 273 282
|
|
TSS Description
|
|
|
|
E8 cw CALL rel16 7+m Call near, displacement relative
|
|
to next instruction
|
|
FF /2 CALL r/m16 7+m/10+m Call near, register
|
|
indirect/memory indirect
|
|
9A cd CALL ptr16:16 17+m,pm=34+m Call intersegment, to full
|
|
pointer given
|
|
9A cd CALL ptr16:16 pm=52+m Call gate, same privilege
|
|
9A cd CALL ptr16:16 pm=86+m Call gate, more privilege, no
|
|
parameters
|
|
9A cd CALL ptr16:16 pm=94+4x+m Call gate, more privilege, x
|
|
parameters
|
|
9A cd CALL ptr16:16 ts Call to task
|
|
FF /3 CALL m16:16 22+m,pm=38+m Call intersegment, address at
|
|
r/m dword
|
|
FF /3 CALL m16:16 pm=56+m Call gate, same privilege
|
|
FF /3 CALL m16:16 pm=90+m Call gate, more privilege, no
|
|
parameters
|
|
FF /3 CALL m16:16 pm=98+4x+m Call gate, more privilege, x
|
|
parameters
|
|
FF /3 CALL m16:16 5 + ts Call to task
|
|
E8 cd CALL rel32 7+m Call near, displacement relative
|
|
to next instruction
|
|
FF /2 CALL r/m32 7+m/10+m Call near, indirect
|
|
9A cp CALL ptr16:32 17+m,pm=34+m Call intersegment, to full
|
|
pointer given
|
|
9A cp CALL ptr16:32 pm=52+m Call gate, same privilege
|
|
9A cp CALL ptr16:32 pm=86+m Call gate, more privilege, no
|
|
parameters
|
|
9A cp CALL ptr32:32 pm=94+4x+m Call gate, more privilege, x
|
|
parameters
|
|
9A cp CALL ptr16:32 ts Call to task
|
|
FF /3 CALL m16:32 22+m,pm=38+m Call intersegment, address at
|
|
r/m dword
|
|
FF /3 CALL m16:32 pm=56+m Call gate, same privilege
|
|
FF /3 CALL m16:32 pm=90+m Call gate, more privilege, no
|
|
parameters
|
|
FF /3 CALL m16:32 pm=98+4x+m Call gate, more privilege, x
|
|
parameters
|
|
FF /3 CALL m16:32 5 + ts Call to task
|
|
|
|
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
NOTE:
|
|
Values of ts are given by the following table:
|
|
|
|
New Task
|
|
386 TSS 386 TSS 286 TSS
|
|
Old VM = 0 VM = 1
|
|
Task Via Task Gate?
|
|
|
|
N Y N Y N Y
|
|
|
|
386 300 309 217 226 273 282
|
|
TSS VM=0
|
|
|
|
286 298 307 217 226 273 282
|
|
TSS
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
|
|
Operation
|
|
|
|
IF rel16 or rel32 type of call
|
|
THEN (* near relative call *)
|
|
IF OperandSize = 16
|
|
THEN
|
|
Push(IP);
|
|
EIP (EIP + rel16) AND 0000FFFFH;
|
|
ELSE (* OperandSize = 32 *)
|
|
Push(EIP);
|
|
EIP EIP + rel32;
|
|
FI;
|
|
FI;
|
|
|
|
IF r/m16 or r/m32 type of call
|
|
THEN (* near absolute call *)
|
|
IF OperandSize = 16
|
|
THEN
|
|
Push(IP);
|
|
EIP [r/m16] AND 0000FFFFH;
|
|
ELSE (* OperandSize = 32 *)
|
|
Push(EIP);
|
|
EIP [r/m32];
|
|
FI;
|
|
FI;
|
|
|
|
IF (PE = 0 OR (PE = 1 AND VM = 1))
|
|
(* real mode or virtual 8086 mode *)
|
|
AND instruction = far CALL
|
|
(* i.e., operand type is m16:16, m16:32, ptr16:16, ptr16:32 *)
|
|
THEN
|
|
IF OperandSize = 16
|
|
THEN
|
|
Push(CS);
|
|
Push(IP); (* address of next instruction; 16 bits *)
|
|
ELSE
|
|
Push(CS); (* padded with 16 high-order bits *)
|
|
Push(EIP); (* address of next instruction; 32 bits *)
|
|
FI;
|
|
IF operand type is m16:16 or m16:32
|
|
THEN (* indirect far call *)
|
|
IF OperandSize = 16
|
|
THEN
|
|
CS:IP [m16:16];
|
|
EIP EIP AND 0000FFFFH; (* clear upper 16 bits *)
|
|
ELSE (* OperandSize = 32 *)
|
|
CS:EIP [m16:32];
|
|
FI;
|
|
FI;
|
|
IF operand type is ptr16:16 or ptr16:32
|
|
THEN (* direct far call *)
|
|
IF OperandSize = 16
|
|
THEN
|
|
CS:IP ptr16:16;
|
|
EIP EIP AND 0000FFFFH; (* clear upper 16 bits *)
|
|
ELSE (* OperandSize = 32 *)
|
|
CS:EIP ptr16:32;
|
|
FI;
|
|
FI;
|
|
FI;
|
|
|
|
IF (PE = 1 AND VM = 0) (* Protected mode, not V86 mode *)
|
|
AND instruction = far CALL
|
|
THEN
|
|
If indirect, then check access of EA doubleword;
|
|
#GP(0) if limit violation;
|
|
New CS selector must not be null else #GP(0);
|
|
Check that new CS selector index is within its
|
|
descriptor table limits; else #GP(new CS selector);
|
|
Examine AR byte of selected descriptor for various legal values;
|
|
depending on value:
|
|
go to CONFORMING-CODE-SEGMENT;
|
|
go to NONCONFORMING-CODE-SEGMENT;
|
|
go to CALL-GATE;
|
|
go to TASK-GATE;
|
|
go to TASK-STATE-SEGMENT;
|
|
ELSE #GP(code segment selector);
|
|
FI;
|
|
|
|
CONFORMING-CODE-SEGMENT:
|
|
DPL must be ó CPL ELSE #GP(code segment selector);
|
|
Segment must be present ELSE #NP(code segment selector);
|
|
Stack must be big enough for return address ELSE #SS(0);
|
|
Instruction pointer must be in code segment limit ELSE #GP(0);
|
|
Load code segment descriptor into CS register;
|
|
Load CS with new code segment selector;
|
|
Load EIP with zero-extend(new offset);
|
|
IF OperandSize=16 THEN EIP EIP AND 0000FFFFH; FI;
|
|
|
|
NONCONFORMING-CODE-SEGMENT:
|
|
RPL must be ó CPL ELSE #GP(code segment selector)
|
|
DPL must be = CPL ELSE #GP(code segment selector)
|
|
Segment must be present ELSE #NP(code segment selector)
|
|
Stack must be big enough for return address ELSE #SS(0)
|
|
Instruction pointer must be in code segment limit ELSE #GP(0)
|
|
Load code segment descriptor into CS register
|
|
Load CS with new code segment selector
|
|
Set RPL of CS to CPL
|
|
Load EIP with zero-extend(new offset);
|
|
IF OperandSize=16 THEN EIP EIP AND 0000FFFFH; FI;
|
|
|
|
CALL-GATE:
|
|
Call gate DPL must be ò CPL ELSE #GP(call gate selector)
|
|
Call gate DPL must be ò RPL ELSE #GP(call gate selector)
|
|
Call gate must be present ELSE #NP(call gate selector)
|
|
Examine code segment selector in call gate descriptor:
|
|
Selector must not be null ELSE #GP(0)
|
|
Selector must be within its descriptor table
|
|
limits ELSE #GP(code segment selector)
|
|
AR byte of selected descriptor must indicate code
|
|
segment ELSE #GP(code segment selector)
|
|
DPL of selected descriptor must be ó CPL ELSE
|
|
#GP(code segment selector)
|
|
IF non-conforming code segment AND DPL < CPL
|
|
THEN go to MORE-PRIVILEGE
|
|
ELSE go to SAME-PRIVILEGE
|
|
FI;
|
|
|
|
MORE-PRIVILEGE:
|
|
Get new SS selector for new privilege level from TSS
|
|
Check selector and descriptor for new SS:
|
|
Selector must not be null ELSE #TS(0)
|
|
Selector index must be within its descriptor
|
|
table limits ELSE #TS(SS selector)
|
|
Selector's RPL must equal DPL of code segment
|
|
ELSE #TS(SS selector)
|
|
Stack segment DPL must equal DPL of code
|
|
segment ELSE #TS(SS selector)
|
|
Descriptor must indicate writable data segment
|
|
ELSE #TS(SS selector)
|
|
Segment present ELSE #SS(SS selector)
|
|
IF OperandSize=32
|
|
THEN
|
|
New stack must have room for parameters plus 16 bytes
|
|
ELSE #SS(0)
|
|
EIP must be in code segment limit ELSE #GP(0)
|
|
Load new SS:eSP value from TSS
|
|
Load new CS:EIP value from gate
|
|
ELSE
|
|
New stack must have room for parameters plus 8 bytes ELSE #SS(0)
|
|
IP must be in code segment limit ELSE #GP(0)
|
|
Load new SS:eSP value from TSS
|
|
Load new CS:IP value from gate
|
|
FI;
|
|
Load CS descriptor
|
|
Load SS descriptor
|
|
Push long pointer of old stack onto new stack
|
|
Get word count from call gate, mask to 5 bits
|
|
Copy parameters from old stack onto new stack
|
|
Push return address onto new stack
|
|
Set CPL to stack segment DPL
|
|
Set RPL of CS to CPL
|
|
|
|
SAME-PRIVILEGE:
|
|
IF OperandSize=32
|
|
THEN
|
|
Stack must have room for 6-byte return address (padded to 8 bytes)
|
|
ELSE #SS(0)
|
|
EIP must be within code segment limit ELSE #GP(0)
|
|
Load CS:EIP from gate
|
|
ELSE
|
|
Stack must have room for 4-byte return address ELSE #SS(0)
|
|
IP must be within code segment limit ELSE #GP(0)
|
|
Load CS:IP from gate
|
|
FI;
|
|
Push return address onto stack
|
|
Load code segment descriptor into CS register
|
|
Set RPL of CS to CPL
|
|
|
|
TASK-GATE:
|
|
Task gate DPL must be ò CPL ELSE #TS(gate selector)
|
|
Task gate DPL must be ò RPL ELSE #TS(gate selector)
|
|
Task Gate must be present ELSE #NP(gate selector)
|
|
Examine selector to TSS, given in Task Gate descriptor:
|
|
Must specify global in the local/global bit ELSE #TS(TSS selector)
|
|
Index must be within GDT limits ELSE #TS(TSS selector)
|
|
TSS descriptor AR byte must specify nonbusy TSS
|
|
ELSE #TS(TSS selector)
|
|
Task State Segment must be present ELSE #NP(TSS selector)
|
|
SWITCH-TASKS (with nesting) to TSS
|
|
IP must be in code segment limit ELSE #TS(0)
|
|
|
|
TASK-STATE-SEGMENT:
|
|
TSS DPL must be ò CPL else #TS(TSS selector)
|
|
TSS DPL must be ò RPL ELSE #TS(TSS selector)
|
|
TSS descriptor AR byte must specify available TSS
|
|
ELSE #TS(TSS selector)
|
|
Task State Segment must be present ELSE #NP(TSS selector)
|
|
SWITCH-TASKS (with nesting) to TSS
|
|
IP must be in code segment limit ELSE #TS(0)
|
|
|
|
Description
|
|
|
|
The CALL instruction causes the procedure named in the operand to be
|
|
executed. When the procedure is complete (a return instruction is executed
|
|
within the procedure), execution continues at the instruction that follows
|
|
the CALL instruction.
|
|
|
|
The action of the different forms of the instruction are described below.
|
|
|
|
Near calls are those with destinations of type r/m16, r/m32, rel16, rel32;
|
|
changing or saving the segment register value is not necessary. The CALL
|
|
rel16 and CALL rel32 forms add a signed offset to the address of the
|
|
instruction following CALL to determine the destination. The rel16 form is
|
|
used when the instruction's operand-size attribute is 16 bits; rel32 is used
|
|
when the operand-size attribute is 32 bits. The result is stored in the
|
|
32-bit EIP register. With rel16, the upper 16 bits of EIP are cleared,
|
|
resulting in an offset whose value does not exceed 16 bits. CALL r/m16 and
|
|
CALL r/m32 specify a register or memory location from which the absolute
|
|
segment offset is fetched. The offset fetched from r/m is 32 bits for an
|
|
operand-size attribute of 32 (r/m32), or 16 bits for an operand-size of 16
|
|
(r/m16). The offset of the instruction following CALL is pushed onto the
|
|
stack. It will be popped by a near RET instruction within the procedure. The
|
|
CS register is not changed by this form of CALL.
|
|
|
|
The far calls, CALL ptr16:16 and CALL ptr16:32, use a four-byte or six-byte
|
|
operand as a long pointer to the procedure called. The CALL m16:16 and
|
|
m16:32 forms fetch the long pointer from the memory location
|
|
specified (indirection). In Real Address Mode or Virtual 8086 Mode, the long
|
|
pointer provides 16 bits for the CS register and 16 or 32 bits for the EIP
|
|
register (depending on the operand-size attribute). These forms of the
|
|
instruction push both CS and IP or EIP as a return address.
|
|
|
|
In Protected Mode, both long pointer forms consult the AR byte in the
|
|
descriptor indexed by the selector part of the long pointer. Depending on
|
|
the value of the AR byte, the call will perform one of the following types
|
|
of control transfers:
|
|
|
|
þ A far call to the same protection level
|
|
þ An inter-protection level far call
|
|
þ A task switch
|
|
|
|
For more information on Protected Mode control transfers, refer to
|
|
Chapter 6 and Chapter 7.
|
|
|
|
Flags Affected
|
|
|
|
All flags are affected if a task switch occurs; no flags are affected if a
|
|
task switch does not occur
|
|
|
|
Protected Mode Exceptions
|
|
|
|
For far calls: #GP, #NP, #SS, and #TS, as indicated in the list above
|
|
|
|
For near direct calls: #GP(0) if procedure location is beyond the code
|
|
segment limits; #SS(0) if pushing the return address exceeds the bounds of
|
|
the stack segment; #PF (fault-code) for a page fault
|
|
|
|
For a near indirect call: #GP(0) for an illegal memory operand effective
|
|
address in the CS, DS, ES, FS, or GS segments; #SS(0) for an illegal address
|
|
in the SS segment; #GP(0) if the indirect offset obtained is beyond the code
|
|
segment limits; #PF(fault-code) for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
|
|
|
|
Notes
|
|
|
|
Any far call from a 32-bit code segment to 16-bit code segments should be
|
|
made from the first 64K bytes of the 32-bit code segment, since the
|
|
operand-size attribute of the instruction is set to 16, thus allowing only a
|
|
16-bit return address offset to be saved.
|
|
|
|
|
|
CBW/CWDE ÄÄ Convert Byte to Word/Convert Word to Doubleword
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
98 CBW 3 AX sign-extend of AL
|
|
98 CWDE 3 EAX sign-extend of AX
|
|
|
|
|
|
Operation
|
|
|
|
IF OperandSize = 16 (* instruction = CBW *)
|
|
THEN AX SignExtend(AL);
|
|
ELSE (* OperandSize = 32, instruction = CWDE *)
|
|
EAX SignExtend(AX);
|
|
FI;
|
|
|
|
Description
|
|
|
|
CBW converts the signed byte in AL to a signed word in AX by extending the
|
|
most significant bit of AL (the sign bit) into all of the bits of AH. CWDE
|
|
converts the signed word in AX to a doubleword in EAX by extending the most
|
|
significant bit of AX into the two most significant bytes of EAX. Note that
|
|
CWDE is different from CWD. CWD uses DX:AX rather than EAX as a destination.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
None
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
None
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
None
|
|
|
|
|
|
CLC ÄÄ Clear Carry Flag
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
F8 CLC 2 Clear carry flag
|
|
|
|
|
|
Operation
|
|
|
|
CF 0;
|
|
|
|
Description
|
|
|
|
CLC sets the carry flag to zero. It does not affect other flags or
|
|
registers.
|
|
|
|
Flags Affected
|
|
|
|
CF = 0
|
|
|
|
Protected Mode Exceptions
|
|
|
|
None
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
None
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
None
|
|
|
|
|
|
CLD ÄÄ Clear Direction Flag
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
FC CLD 2 Clear direction flag; SI and DI
|
|
will increment during string
|
|
instructions
|
|
|
|
|
|
Operation
|
|
|
|
DF 0;
|
|
|
|
Description
|
|
|
|
CLD clears the direction flag. No other flags or registers are affected.
|
|
After CLD is executed, string operations will increment the index registers
|
|
(SI and/or DI) that they use.
|
|
|
|
Flags Affected
|
|
|
|
DF = 0
|
|
|
|
Protected Mode Exceptions
|
|
|
|
None
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
None
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
None
|
|
|
|
|
|
CLI ÄÄ Clear Interrupt Flag
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
FA CLI 3 Clear interrupt flag; interrupts disabled
|
|
|
|
|
|
Operation
|
|
|
|
IF 0;
|
|
|
|
Description
|
|
|
|
CLI clears the interrupt flag if the current privilege level is at least as
|
|
privileged as IOPL. No other flags are affected. External interrupts are not
|
|
recognized at the end of the CLI instruction or from that point on until the
|
|
interrupt flag is set.
|
|
|
|
Flags Affected
|
|
|
|
IF = 0
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the current privilege level is greater (has less privilege) than
|
|
the IOPL in the flags register. IOPL specifies the least privileged level at
|
|
which I/O can be performed.
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
None
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
#GP(0) as for Protected Mode
|
|
|
|
|
|
CLTS ÄÄ Clear Task-Switched Flag in CR0
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
OF 06 CLTS 5 Clear task-switched flag
|
|
|
|
|
|
Operation
|
|
|
|
TS Flag in CR0 0;
|
|
|
|
Description
|
|
|
|
CLTS clears the task-switched (TS) flag in register CR0. This flag is set by
|
|
the 80386 every time a task switch occurs. The TS flag is used to manage
|
|
processor extensions as follows:
|
|
|
|
þ Every execution of an ESC instruction is trapped if the TS flag is set.
|
|
|
|
þ Execution of a WAIT instruction is trapped if the MP flag and the TS
|
|
flag are both set.
|
|
|
|
Thus, if a task switch was made after an ESC instruction was begun, the
|
|
processor extension's context may need to be saved before a new ESC
|
|
instruction can be issued. The fault handler saves the context and resets
|
|
the TS flag.
|
|
|
|
CLTS appears in operating system software, not in application programs. It
|
|
is a privileged instruction that can only be executed at privilege level 0.
|
|
|
|
Flags Affected
|
|
|
|
TS = 0 (TS is in CR0, not the flag register)
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if CLTS is executed with a current privilege level other than 0
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
None (valid in Real Address Mode to allow initialization for Protected
|
|
Mode)
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode
|
|
|
|
|
|
CMC ÄÄ Complement Carry Flag
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
F5 CMC 2 Complement carry flag
|
|
|
|
|
|
Operation
|
|
|
|
CF NOT CF;
|
|
|
|
Description
|
|
|
|
CMC reverses the setting of the carry flag. No other flags are affected.
|
|
|
|
Flags Affected
|
|
|
|
CF as described above
|
|
|
|
Protected Mode Exceptions
|
|
|
|
None
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
None
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
None
|
|
|
|
|
|
CMP ÄÄ Compare Two Operands
|
|
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
3C ib CMP AL,imm8 2 Compare immediate byte to AL
|
|
3D iw CMP AX,imm16 2 Compare immediate word to AX
|
|
3D id CMP EAX,imm32 2 Compare immediate dword to EAX
|
|
80 /7 ib CMP r/m8,imm8 2/5 Compare immediate byte to r/m
|
|
byte
|
|
81 /7 iw CMP r/m16,imm16 2/5 Compare immediate word to r/m
|
|
word
|
|
81 /7 id CMP r/m32,imm32 2/5 Compare immediate dword to r/m
|
|
dword
|
|
83 /7 ib CMP r/m16,imm8 2/5 Compare sign extended immediate
|
|
byte to r/m word
|
|
83 /7 ib CMP r/m32,imm8 2/5 Compare sign extended immediate
|
|
byte to r/m dword
|
|
38 /r CMP r/m8,r8 2/5 Compare byte register to r/m
|
|
byte
|
|
39 /r CMP r/m16,r16 2/5 Compare word register to r/m
|
|
word
|
|
39 /r CMP r/m32,r32 2/5 Compare dword register to r/m
|
|
dword
|
|
3A /r CMP r8,r/m8 2/6 Compare r/m byte to byte
|
|
register
|
|
3B /r CMP r16,r/m16 2/6 Compare r/m word to word
|
|
register
|
|
3B /r CMP r32,r/m32 2/6 Compare r/m dword to dword
|
|
register
|
|
|
|
|
|
Operation
|
|
|
|
LeftSRC - SignExtend(RightSRC);
|
|
(* CMP does not store a result; its purpose is to set the flags *)
|
|
|
|
Description
|
|
|
|
CMP subtracts the second operand from the first but, unlike the SUB
|
|
instruction, does not store the result; only the flags are changed. CMP is
|
|
typically used in conjunction with conditional jumps and the SETcc
|
|
instruction. (Refer to Appendix D for the list of signed and unsigned flag
|
|
tests provided.) If an operand greater than one byte is compared to an
|
|
immediate byte, the byte value is first sign-extended.
|
|
|
|
Flags Affected
|
|
|
|
OF, SF, ZF, AF, PF, and CF as described in Appendix C
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) for an illegal memory operand effective address in the CS, DS, ES,
|
|
FS, or GS segments; #SS(0) for an illegal address in the SS segment;
|
|
#PF(fault-code) for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
|
|
|
|
|
|
CMPS/CMPSB/CMPSW/CMPSD ÄÄ Compare String Operands
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
A6 CMPS m8,m8 10 Compare bytes ES:[(E)DI] (second
|
|
operand) with [(E)SI] (first
|
|
operand)
|
|
A7 CMPS m16,m16 10 Compare words ES:[(E)DI] (second
|
|
operand) with [(E)SI] (first
|
|
operand)
|
|
A7 CMPS m32,m32 10 Compare dwords ES:[(E)DI]
|
|
(second operand) with [(E)SI]
|
|
(first operand)
|
|
A6 CMPSB 10 Compare bytes ES:[(E)DI] with
|
|
DS:[SI]
|
|
A7 CMPSW 10 Compare words ES:[(E)DI] with
|
|
DS:[SI]
|
|
A7 CMPSD 10 Compare dwords ES:[(E)DI] with
|
|
DS:[SI]
|
|
|
|
|
|
Operation
|
|
|
|
IF (instruction = CMPSD) OR
|
|
(instruction has operands of type DWORD)
|
|
THEN OperandSize 32;
|
|
ELSE OperandSize 16;
|
|
FI;
|
|
IF AddressSize = 16
|
|
THEN
|
|
use SI for source-index and DI for destination-index
|
|
ELSE (* AddressSize = 32 *)
|
|
use ESI for source-index and EDI for destination-index;
|
|
FI;
|
|
IF byte type of instruction
|
|
THEN
|
|
[source-index] - [destination-index]; (* byte comparison *)
|
|
IF DF = 0 THEN IncDec 1 ELSE IncDec -1; FI;
|
|
ELSE
|
|
IF OperandSize = 16
|
|
THEN
|
|
[source-index] - [destination-index]; (* word comparison *)
|
|
IF DF = 0 THEN IncDec 2 ELSE IncDec -2; FI;
|
|
ELSE (* OperandSize = 32 *)
|
|
[source-index] - [destination-index]; (* dword comparison *)
|
|
IF DF = 0 THEN IncDec 4 ELSE IncDec -4; FI;
|
|
FI;
|
|
FI;
|
|
source-index = source-index + IncDec;
|
|
destination-index = destination-index + IncDec;
|
|
|
|
Description
|
|
|
|
CMPS compares the byte, word, or doubleword pointed to by the source-index
|
|
register with the byte, word, or doubleword pointed to by the
|
|
destination-index register.
|
|
|
|
If the address-size attribute of this instruction is 16 bits, SI and DI
|
|
will be used for source- and destination-index registers; otherwise ESI and
|
|
EDI will be used. Load the correct index values into SI and DI (or ESI and
|
|
EDI) before executing CMPS.
|
|
|
|
The comparison is done by subtracting the operand indexed by
|
|
the destination-index register from the operand indexed by the source-index
|
|
register.
|
|
|
|
Note that the direction of subtraction for CMPS is [SI] - [DI] or
|
|
[ESI] - [EDI]. The left operand (SI or ESI) is the source and the right
|
|
operand (DI or EDI) is the destination. This is the reverse of the usual
|
|
Intel convention in which the left operand is the destination and the right
|
|
operand is the source.
|
|
|
|
The result of the subtraction is not stored; only the flags reflect the
|
|
change. The types of the operands determine whether bytes, words, or
|
|
doublewords are compared. For the first operand (SI or ESI), the DS register
|
|
is used, unless a segment override byte is present. The second operand (DI
|
|
or EDI) must be addressable from the ES register; no segment override is
|
|
possible.
|
|
|
|
After the comparison is made, both the source-index register and
|
|
destination-index register are automatically advanced. If the direction flag
|
|
is 0 (CLD was executed), the registers increment; if the direction flag is 1
|
|
(STD was executed), the registers decrement. The registers increment or
|
|
decrement by 1 if a byte is compared, by 2 if a word is compared, or by 4 if
|
|
a doubleword is compared.
|
|
|
|
CMPSB, CMPSW and CMPSD are synonyms for the byte, word, and
|
|
doubleword CMPS instructions, respectively.
|
|
|
|
CMPS can be preceded by the REPE or REPNE prefix for block comparison of CX
|
|
or ECX bytes, words, or doublewords. Refer to the description of the REP
|
|
instruction for more information on this operation.
|
|
|
|
Flags Affected
|
|
|
|
OF, SF, ZF, AF, PF, and CF as described in Appendix C
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) for an illegal memory operand effective address in the CS, DS, ES,
|
|
FS, or GS segments; #SS(0) for an illegal address in the SS segment;
|
|
#PF(fault-code) for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF (fault-code) for a page fault
|
|
|
|
|
|
CWD/CDQ ÄÄ Convert Word to Doubleword/Convert Doubleword to
|
|
Quadword
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
99 CWD 2 DX:AX sign-extend of AX
|
|
99 CDQ 2 EDX:EAX sign-extend of EAX
|
|
|
|
|
|
Operation
|
|
|
|
IF OperandSize = 16 (* CWD instruction *)
|
|
THEN
|
|
IF AX < 0 THEN DX 0FFFFH; ELSE DX 0; FI;
|
|
ELSE (* OperandSize = 32, CDQ instruction *)
|
|
IF EAX < 0 THEN EDX 0FFFFFFFFH; ELSE EDX 0; FI;
|
|
FI;
|
|
|
|
Description
|
|
|
|
CWD converts the signed word in AX to a signed doubleword in DX:AX
|
|
by extending the most significant bit of AX into all the bits of DX. CDQ
|
|
converts the signed doubleword in EAX to a signed 64-bit integer in the
|
|
register pair EDX:EAX by extending the most significant bit of EAX
|
|
(the sign bit) into all the bits of EDX. Note that CWD is different from
|
|
CWDE. CWDE uses EAX as a destination, instead of DX:AX.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
None
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
None
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
None
|
|
|
|
|
|
DAA ÄÄ Decimal Adjust AL after Addition
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
27 DAA 4 Decimal adjust AL after addition
|
|
|
|
|
|
Operation
|
|
|
|
IF ((AL AND 0FH) > 9) OR (AF = 1)
|
|
THEN
|
|
AL AL + 6;
|
|
AF 1;
|
|
ELSE
|
|
AF 0;
|
|
FI;
|
|
IF (AL > 9FH) OR (CF = 1)
|
|
THEN
|
|
AL AL + 60H;
|
|
CF 1;
|
|
ELSE CF 0;
|
|
FI;
|
|
|
|
Description
|
|
|
|
Execute DAA only after executing an ADD instruction that leaves a
|
|
two-BCD-digit byte result in the AL register. The ADD operands should
|
|
consist of two packed BCD digits. The DAA instruction adjusts AL to
|
|
contain the correct two-digit packed decimal result.
|
|
|
|
Flags Affected
|
|
|
|
AF and CF as described above; SF, ZF, PF, and CF as described in
|
|
Appendix C.
|
|
|
|
Protected Mode Exceptions
|
|
|
|
None
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
None
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
None
|
|
|
|
|
|
DAS ÄÄ Decimal Adjust AL after Subtraction
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
2F DAS 4 Decimal adjust AL after subtraction
|
|
|
|
|
|
Operation
|
|
|
|
IF (AL AND 0FH) > 9 OR AF = 1
|
|
THEN
|
|
AL AL - 6;
|
|
AF 1;
|
|
ELSE
|
|
AF 0;
|
|
FI;
|
|
IF (AL > 9FH) OR (CF = 1)
|
|
THEN
|
|
AL AL - 60H;
|
|
CF 1;
|
|
ELSE CF 0;
|
|
FI;
|
|
|
|
Description
|
|
|
|
Execute DAS only after a subtraction instruction that leaves a
|
|
two-BCD-digit byte result in the AL register. The operands should consist
|
|
of two packed BCD digits. DAS adjusts AL to contain the correct packed
|
|
two-digit decimal result.
|
|
|
|
Flags Affected
|
|
|
|
AF and CF as described above; SF, ZF, and PF as described in Appendix C.
|
|
|
|
Protected Mode Exceptions
|
|
|
|
None
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
None
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
None
|
|
|
|
|
|
DEC ÄÄ Decrement by 1
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
FE /1 DEC r/m8 2/6 Decrement r/m byte by 1
|
|
FF /1 DEC r/m16 2/6 Decrement r/m word by 1
|
|
DEC r/m32 2/6 Decrement r/m dword by 1
|
|
48+rw DEC r16 2 Decrement word register by 1
|
|
48+rw DEC r32 2 Decrement dword register by 1
|
|
|
|
|
|
Operation
|
|
|
|
DEST DEST - 1;
|
|
|
|
Description
|
|
|
|
DEC subtracts 1 from the operand. DEC does not change the carry flag.
|
|
To affect the carry flag, use the SUB instruction with an immediate
|
|
operand of 1.
|
|
|
|
Flags Affected
|
|
|
|
OF, SF, ZF, AF, and PF as described in Appendix C.
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the result is a nonwritable segment; #GP(0) for an illegal
|
|
memory operand effective address in the CS, DS, ES, FS, or GS
|
|
segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code)
|
|
for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
|
|
fault
|
|
|
|
|
|
DIV ÄÄ Unsigned Divide
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
F6 /6 DIV AL,r/m8 14/17 Unsigned divide AX by r/m byte
|
|
(AL=Quo, AH=Rem)
|
|
F7 /6 DIV AX,r/m16 22/25 Unsigned divide DX:AX by r/m
|
|
word (AX=Quo, DX=Rem)
|
|
F7 /6 DIV EAX,r/m32 38/41 Unsigned divide EDX:EAX by r/m
|
|
dword (EAX=Quo, EDX=Rem)
|
|
|
|
|
|
Operation
|
|
|
|
temp dividend / divisor;
|
|
IF temp does not fit in quotient
|
|
THEN Interrupt 0;
|
|
ELSE
|
|
quotient temp;
|
|
remainder dividend MOD (r/m);
|
|
FI;
|
|
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
Note:
|
|
Divisions are unsigned. The divisor is given by the r/m operand.
|
|
The dividend, quotient, and remainder use implicit registers. Refer to
|
|
the table under "Description."
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
|
|
Description
|
|
|
|
DIV performs an unsigned division. The dividend is implicit; only the
|
|
divisor is given as an operand. The remainder is always less than the
|
|
divisor. The type of the divisor determines which registers to use as
|
|
follows:
|
|
|
|
Size Dividend Divisor Quotient Remainder
|
|
byte AX r/m8 AL AH
|
|
word DX:AX r/m16 AX DX
|
|
dword EDX:EAX r/m32 EAX EDX
|
|
|
|
Flags Affected
|
|
|
|
OF, SF, ZF, AR, PF, CF are undefined.
|
|
|
|
Protected Mode Exceptions
|
|
|
|
Interrupt 0 if the quotient is too large to fit in the designated register
|
|
(AL, AX, or EAX), or if the divisor is 0; #GP(0) for an illegal memory
|
|
operand effective address in the CS, DS, ES, FS, or GS segments; #SS(0)
|
|
for an illegal address in the SS segment; #PF(fault-code) for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 0 if the quotient is too big to fit in the designated register
|
|
(AL, AX, or EAX), or if the divisor is 0; Interrupt 13 if any part of the
|
|
operand would lie outside of the effective address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
|
|
fault
|
|
|
|
|
|
ENTER ÄÄ Make Stack Frame for Procedure Parameters
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
C8 iw 00 ENTER imm16,0 10 Make procedure stack frame
|
|
C8 iw 01 ENTER imm16,1 12 Make stack frame for procedure
|
|
parameters
|
|
C8 iw ib ENTER imm16,imm8 15+4(n-1) Make stack frame for
|
|
procedure parameters
|
|
|
|
|
|
Operation
|
|
|
|
level level MOD 32
|
|
IF OperandSize = 16 THEN Push(BP) ELSE Push (EBP) FI;
|
|
(* Save stack pointer *)
|
|
frame-ptr eSP
|
|
IF level > 0
|
|
THEN (* level is rightmost parameter *)
|
|
FOR i 1 TO level - 1
|
|
DO
|
|
IF OperandSize = 16
|
|
THEN
|
|
BP BP - 2;
|
|
Push[BP]
|
|
ELSE (* OperandSize = 32 *)
|
|
EBP EBP - 4;
|
|
Push[EBP];
|
|
FI;
|
|
OD;
|
|
Push(frame-ptr)
|
|
FI;
|
|
IF OperandSize = 16 THEN BP frame-ptr ELSE EBP frame-ptr; FI;
|
|
IF StackAddrSize = 16
|
|
THEN SP SP - First operand;
|
|
ELSE ESP ESP - ZeroExtend(First operand);
|
|
FI;
|
|
|
|
Description
|
|
|
|
ENTER creates the stack frame required by most block-structured
|
|
high-level languages. The first operand specifies the number of bytes of
|
|
dynamic storage allocated on the stack for the routine being entered.
|
|
The second operand gives the lexical nesting level (0 to 31) of the routine
|
|
within the high-level language source code. It determines the number of
|
|
stack frame pointers copied into the new stack frame from the preceding
|
|
frame. BP (or EBP, if the operand-size attribute is 32 bits) is the current
|
|
stack frame pointer.
|
|
|
|
If the operand-size attribute is 16 bits, the processor uses BP as the
|
|
frame pointer and SP as the stack pointer. If the operand-size attribute is
|
|
32 bits, the processor uses EBP for the frame pointer and ESP for the stack
|
|
pointer.
|
|
|
|
If the second operand is 0, ENTER pushes the frame pointer (BP or
|
|
EBP) onto the stack; ENTER then subtracts the first operand from the
|
|
stack pointer and sets the frame pointer to the current stack-pointer
|
|
value.
|
|
|
|
For example, a procedure with 12 bytes of local variables would have an
|
|
ENTER 12,0 instruction at its entry point and a LEAVE instruction
|
|
before every RET. The 12 local bytes would be addressed as negative
|
|
offsets from the frame pointer.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#SS(0) if SP or ESP would exceed the stack limit at any point during
|
|
instruction execution; #PF(fault-code) for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
None
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
None
|
|
|
|
|
|
HLT ÄÄ Halt
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
F4 HLT 5 Halt
|
|
|
|
|
|
Operation
|
|
|
|
Enter Halt state;
|
|
|
|
Description
|
|
|
|
HALT stops instruction execution and places the 80386 in a HALT state.
|
|
An enabled interrupt, NMI, or a reset will resume execution. If an
|
|
interrupt (including NMI) is used to resume execution after HLT, the saved
|
|
CS:IP (or CS:EIP) value points to the instruction following HLT.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
HLT is a privileged instruction; #GP(0) if the current privilege level is
|
|
not 0
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
None
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
#GP(0); HLT is a privileged instruction
|
|
|
|
|
|
IDIV ÄÄ Signed Divide
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
F6 /7 IDIV r/m8 19 Signed divide AX by r/m byte
|
|
(AL=Quo, AH=Rem)
|
|
F7 /7 IDIV AX,r/m16 27 Signed divide DX:AX by EA word
|
|
(AX=Quo, DX=Rem)
|
|
F7 /7 IDIV EAX,r/m32 43 Signed divide EDX:EAX by DWORD
|
|
byte (EAX=Quo, EDX=Rem)
|
|
|
|
|
|
Operation
|
|
|
|
temp dividend / divisor;
|
|
IF temp does not fit in quotient
|
|
THEN Interrupt 0;
|
|
ELSE
|
|
quotient temp;
|
|
remainder dividend MOD (r/m);
|
|
FI;
|
|
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
Notes:
|
|
Divisions are signed. The divisor is given by the r/m operand. The
|
|
dividend, quotient, and remainder use implicit registers. Refer to the
|
|
table under "Description."
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
|
|
Description
|
|
|
|
IDIV performs a signed division. The dividend, quotient, and remainder
|
|
are implicitly allocated to fixed registers. Only the divisor is given as
|
|
an explicit r/m operand. The type of the divisor determines which registers
|
|
to use as follows:
|
|
|
|
Size Divisor Quotient Remainder Dividend
|
|
byte r/m8 AL AH AX
|
|
word r/m16 AX DX DX:AX
|
|
dword r/m32 EAX EDX EDX:EAX
|
|
|
|
If the resulting quotient is too large to fit in the destination, or if the
|
|
division is 0, an Interrupt 0 is generated. Nonintegral quotients are
|
|
truncated toward 0. The remainder has the same sign as the dividend
|
|
and the absolute value of the remainder is always less than the absolute
|
|
value of the divisor.
|
|
|
|
Flags Affected
|
|
|
|
OF, SF, ZF, AR, PF, CF are undefined.
|
|
|
|
Protected Mode Exceptions
|
|
|
|
Interrupt 0 if the quotient is too large to fit in the designated register
|
|
(AL or AX), or if the divisor is 0; #GP (0) for an illegal memory operand
|
|
effective address in the CS, DS, ES, FS, or GS segments; #SS(0) for an
|
|
illegal address in the SS segment; #PF(fault-code) for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 0 if the quotient is too large to fit in the designated register
|
|
(AL or AX), or if the divisor is 0; Interrupt 13 if any part of the operand
|
|
would lie outside of the effective address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
|
|
fault
|
|
|
|
|
|
IMUL ÄÄ Signed Multiply
|
|
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
F6 /5 IMUL r/m8 9-14/12-17 AX AL * r/m byte
|
|
F7 /5 IMUL r/m16 9-22/12-25 DX:AX AX * r/m word
|
|
F7 /5 IMUL r/m32 9-38/12-41 EDX:EAX EAX * r/m dword
|
|
0F AF /r IMUL r16,r/m16 9-22/12-25 word register word
|
|
register * r/m word
|
|
0F AF /r IMUL r32,r/m32 9-38/12-41 dword register dword
|
|
register * r/m dword
|
|
6B /r ib IMUL r16,r/m16,imm8 9-14/12-17 word register r/m16 *
|
|
sign-extended immediate byte
|
|
6B /r ib IMUL r32,r/m32,imm8 9-14/12-17 dword register r/m32 *
|
|
sign-extended immediate byte
|
|
6B /r ib IMUL r16,imm8 9-14/12-17 word register word
|
|
register * sign-extended
|
|
immediate byte
|
|
6B /r ib IMUL r32,imm8 9-14/12-17 dword register dword
|
|
register * sign-extended
|
|
immediate byte
|
|
69 /r iw IMUL r16,r/m16,imm16 9-22/12-25 word register r/m16 *
|
|
immediate word
|
|
69 /r id IMUL r32,r/m32,imm32 9-38/12-41 dword register r/m32 *
|
|
immediate dword
|
|
69 /r iw IMUL r16,imm16 9-22/12-25 word register r/m16 *
|
|
immediate word
|
|
69 /r id IMUL r32,imm32 9-38/12-41 dword register r/m32 *
|
|
immediate dword
|
|
|
|
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
NOTES:
|
|
The 80386 uses an early-out multiply algorithm. The actual number of
|
|
clocks depends on the position of the most significant bit in the
|
|
optimizing multiplier, shown underlined above. The optimization occurs for
|
|
positive and negative values. Because of the early-out algorithm, clock
|
|
counts given are minimum to maximum. To calculate the actual clocks, use
|
|
the following formula:
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
|
|
Actual clock = if m <> 0 then max(ceiling(log{2} ³m³), 3) + 6 clocks
|
|
Actual clock = if m = 0 then 9 clocks
|
|
(where m is the multiplier)
|
|
|
|
Add three clocks if the multiplier is a memory operand.
|
|
|
|
Operation
|
|
|
|
result multiplicand * multiplier;
|
|
|
|
Description
|
|
|
|
IMUL performs signed multiplication. Some forms of the instruction
|
|
use implicit register operands. The operand combinations for all forms
|
|
of the instruction are shown in the "Description" column above.
|
|
|
|
IMUL clears the overflow and carry flags under the following conditions:
|
|
|
|
Instruction Form Condition for Clearing CF and OF
|
|
r/m8 AL = sign-extend of AL to 16 bits
|
|
r/m16 AX = sign-extend of AX to 32 bits
|
|
r/m32 EDX:EAX = sign-extend of EAX to 32 bits
|
|
r16,r/m16 Result exactly fits within r16
|
|
r/32,r/m32 Result exactly fits within r32
|
|
r16,r/m16,imm16 Result exactly fits within r16
|
|
r32,r/m32,imm32 Result exactly fits within r32
|
|
|
|
Flags Affected
|
|
|
|
OF and CF as described above; SF, ZF, AF, and PF are undefined
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) for an illegal memory operand effective address in the CS, DS,
|
|
ES, FS, or GS segments; #SS(0) for an illegal address in the SS segment;
|
|
#PF(fault-code) for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exeptions as in Real Address Mode; #PF(fault-code) for a page
|
|
fault
|
|
|
|
Notes
|
|
|
|
When using the accumulator forms (IMUL r/m8, IMUL r/m16, or IMUL
|
|
r/m32), the result of the multiplication is available even if the overflow
|
|
flag is set because the result is two times the size of the multiplicand
|
|
and multiplier. This is large enough to handle any possible result.
|
|
|
|
|
|
IN ÄÄ Input from Port
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
E4 ib IN AL,imm8 12,pm=6*/26** Input byte from immediate port
|
|
into AL
|
|
E5 ib IN AX,imm8 12,pm=6*/26** Input word from immediate port
|
|
into AX
|
|
E5 ib IN EAX,imm8 12,pm=6*/26** Input dword from immediate port
|
|
into EAX
|
|
EC IN AL,DX 13,pm=7*/27** Input byte from port DX into AL
|
|
ED IN AX,DX 13,pm=7*/27** Input word from port DX into AX
|
|
ED IN EAX,DX 13,pm=7*/27** Input dword from port DX into
|
|
EAX
|
|
|
|
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
NOTES:
|
|
*If CPL ó IOPL
|
|
**If CPL > IOPL or if in virtual 8086 mode
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
|
|
Operation
|
|
|
|
IF (PE = 1) AND ((VM = 1) OR (CPL > IOPL))
|
|
THEN (* Virtual 8086 mode, or protected mode with CPL > IOPL *)
|
|
IF NOT I-O-Permission (SRC, width(SRC))
|
|
THEN #GP(0);
|
|
FI;
|
|
FI;
|
|
DEST [SRC]; (* Reads from I/O address space *)
|
|
|
|
Description
|
|
|
|
IN transfers a data byte or data word from the port numbered by the
|
|
second operand into the register (AL, AX, or EAX) specified by the first
|
|
operand. Access any port from 0 to 65535 by placing the port number
|
|
in the DX register and using an IN instruction with DX as the second
|
|
parameter. These I/O instructions can be shortened by using an 8-bit
|
|
port I/O in the instruction. The upper eight bits of the port address will
|
|
be 0 when 8-bit port I/O is used.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the current privilege level is larger (has less privilege) than
|
|
IOPL and any of the corresponding I/O permission bits in TSS equals 1
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
None
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
#GP(0) fault if any of the corresponding I/O permission bits in TSS
|
|
equals 1
|
|
|
|
|
|
INC ÄÄ Increment by 1
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
FE /0 INC r/m8 Increment r/m byte by 1
|
|
FF /0 INC r/m16 Increment r/m word by 1
|
|
FF /6 INC r/m32 Increment r/m dword by 1
|
|
40 + rw INC r16 Increment word register by 1
|
|
40 + rd INC r32 Increment dword register by 1
|
|
|
|
|
|
Operation
|
|
|
|
DEST DEST + 1;
|
|
|
|
Description
|
|
|
|
INC adds 1 to the operand. It does not change the carry flag. To affect
|
|
the carry flag, use the ADD instruction with a second operand of 1.
|
|
|
|
Flags Affected
|
|
|
|
OF, SF, ZF, AF, and PF as described in Appendix C
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the operand is in a nonwritable segment; #GP(0) for an illegal
|
|
memory operand effective address in the CS, DS, ES, FS, or GS
|
|
segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code)
|
|
for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
|
|
fault
|
|
|
|
|
|
INS/INSB/INSW/INSD ÄÄ Input from Port to String
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
6C INS r/m8,DX 15,pm=9*/29** Input byte from port DX into ES:(E)DI
|
|
6D INS r/m16,DX 15,pm=9*/29** Input word from port DX into ES:(E)DI
|
|
6D INS r/m32,DX 15,pm=9*/29** Input dword from port DX into ES:(E)DI
|
|
6C INSB 15,pm=9*/29** Input byte from port DX into ES:(E)DI
|
|
6D INSW 15,pm=9*/29** Input word from port DX into ES:(E)DI
|
|
6D INSD 15,pm=9*/29** Input dword from port DX into ES:(E)DI
|
|
|
|
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
NOTES:
|
|
*If CPL ó IOPL
|
|
**If CPL > IOPL or if in virtual 8086 mode
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
|
|
Operation
|
|
|
|
IF AddressSize = 16
|
|
THEN use DI for dest-index;
|
|
ELSE (* AddressSize = 32 *)
|
|
use EDI for dest-index;
|
|
FI;
|
|
IF (PE = 1) AND ((VM = 1) OR (CPL > IOPL))
|
|
THEN (* Virtual 8086 mode, or protected mode with CPL > IOPL *)
|
|
IF NOT I-O-Permission (SRC, width(SRC))
|
|
THEN #GP(0);
|
|
FI;
|
|
FI;
|
|
IF byte type of instruction
|
|
THEN
|
|
ES:[dest-index] [DX]; (* Reads byte at DX from I/O address space *)
|
|
IF DF = 0 THEN IncDec 1 ELSE IncDec -1; FI;
|
|
FI;
|
|
IF OperandSize = 16
|
|
THEN
|
|
ES:[dest-index] [DX]; (* Reads word at DX from I/O address space *)
|
|
IF DF = 0 THEN IncDec 2 ELSE IncDec -2; FI;
|
|
FI;
|
|
IF OperandSize = 32
|
|
THEN
|
|
ES:[dest-index] [DX]; (* Reads dword at DX from I/O address space *)
|
|
IF DF = 0 THEN IncDec 4 ELSE IncDec -4; FI;
|
|
FI;
|
|
dest-index dest-index + IncDec;
|
|
|
|
Description
|
|
|
|
INS transfers data from the input port numbered by the DX register to
|
|
the memory byte or word at ES:dest-index. The memory operand must
|
|
be addressable from ES; no segment override is possible. The destination
|
|
register is DI if the address-size attribute of the instruction is 16 bits,
|
|
or EDI if the address-size attribute is 32 bits.
|
|
|
|
INS does not allow the specification of the port number as an immediate
|
|
value. The port must be addressed through the DX register value. Load
|
|
the correct value into DX before executing the INS instruction.
|
|
|
|
The destination address is determined by the contents of the destination
|
|
index register. Load the correct index into the destination index register
|
|
before executing INS.
|
|
|
|
After the transfer is made, DI or EDI advances automatically. If the
|
|
direction flag is 0 (CLD was executed), DI or EDI increments; if the
|
|
direction flag is 1 (STD was executed), DI or EDI decrements. DI
|
|
increments or decrements by 1 if a byte is input, by 2 if a word is input,
|
|
or by 4 if a doubleword is input.
|
|
|
|
INSB, INSW and INSD are synonyms of the byte, word, and doubleword
|
|
INS instructions. INS can be preceded by the REP prefix for block input of
|
|
CX bytes or words. Refer to the REP instruction for details of this
|
|
operation.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if CPL is numerically greater than IOPL and any of the
|
|
corresponding I/O permission bits in TSS equals 1; #GP(0) if the
|
|
destination is in a nonwritable segment; #GP(0) for an illegal memory
|
|
operand effective address in the CS, DS, ES, FS, or GS segments; #SS(0) for
|
|
an illegal address in the SS segment; #PF(fault-code) for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
#GP(0) fault if any of the corresponding I/O permission bits in TSS
|
|
equals 1; #PF(fault-code) for a page fault
|
|
|
|
|
|
INT/INTO ÄÄ Call to Interrupt Procedure
|
|
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
CC INT 3 33 Interrupt 3--trap to debugger
|
|
CC INT 3 pm=59 Interrupt 3--Protected Mode, same
|
|
privilege
|
|
CC INT 3 pm=99 Interrupt 3--Protected Mode, more
|
|
privilege
|
|
CC INT 3 pm=119 Interrupt 3--from V86 mode to PL 0
|
|
CC INT 3 ts Interrupt 3--Protected Mode, via
|
|
task gate
|
|
CD ib INT imm8 37 Interrupt numbered by immediate
|
|
byte
|
|
CD ib INT imm8 pm=59 Interrupt--Protected Mode, same
|
|
privilege
|
|
CD ib INT imm8 pm=99 Interrupt--Protected Mode, more
|
|
privilege
|
|
CD ib INT imm8 pm=119 Interrupt--from V86 mode to PL 0
|
|
CD ib INT imm8 ts Interrupt--Protected Mode, via task
|
|
gate
|
|
CE INTO Fail:3,pm=3;
|
|
Pass:35 Interrupt 4--if overflow flag is 1
|
|
CE INTO pm=59 Interrupt 4--Protected Mode, same
|
|
privilege
|
|
CE INTO pm=99 Interrupt 4--Protected Mode, more
|
|
privilege
|
|
CE INTO pm=119 Interrupt 4--from V86 mode to PL 0
|
|
CE INTO ts Interrupt 4--Protected Mode, via
|
|
task gate
|
|
|
|
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
NOTE:
|
|
Approximate values of ts are given by the following table:
|
|
|
|
New Task
|
|
|
|
Old Task 386 TSS 386 TSS 286 TSS
|
|
VM = 0 VM = 1
|
|
|
|
386
|
|
TSS VM=0 309 226 282
|
|
|
|
386
|
|
TSS VM=1 314 231 287
|
|
|
|
286
|
|
TSS 307 224 280
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
|
|
Operation
|
|
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
NOTE:
|
|
The following operational description applies not only to the
|
|
above instructions but also to external interrupts and exceptions.
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
|
|
IF PE = 0
|
|
THEN GOTO REAL-ADDRESS-MODE;
|
|
ELSE GOTO PROTECTED-MODE;
|
|
FI;
|
|
|
|
REAL-ADDRESS-MODE:
|
|
Push (FLAGS);
|
|
IF 0; (* Clear interrupt flag *)
|
|
TF 0; (* Clear trap flag *)
|
|
Push(CS);
|
|
Push(IP);
|
|
(* No error codes are pushed *)
|
|
CS IDT[Interrupt number * 4].selector;
|
|
IP IDT[Interrupt number * 4].offset;
|
|
|
|
PROTECTED-MODE:
|
|
Interrupt vector must be within IDT table limits,
|
|
else #GP(vector number * 8+2+EXT);
|
|
Descriptor AR byte must indicate interrupt gate, trap gate, or task gate,
|
|
else #GP(vector number * 8+2+EXT);
|
|
IF software interrupt (* i.e. caused by INT n, INT 3, or INTO *)
|
|
THEN
|
|
IF gate descriptor DPL < CPL
|
|
THEN #GP(vector number * 8+2+EXT);
|
|
FI;
|
|
FI;
|
|
Gate must be present, else #NP(vector number * 8+2+EXT);
|
|
IF trap gate OR interrupt gate
|
|
THEN GOTO TRAP-GATE-OR-INTERRUPT-GATE;
|
|
ELSE GOTO TASK-GATE;
|
|
FI;
|
|
|
|
TRAP-GATE-OR-INTERRUPT-GATE:
|
|
Examine CS selector and descriptor given in the gate descriptor;
|
|
Selector must be non-null, else #GP (EXT);
|
|
Selector must be within its descriptor table limits
|
|
ELSE #GP(selector+EXT);
|
|
Descriptor AR byte must indicate code segment
|
|
ELSE #GP(selector + EXT);
|
|
Segment must be present, else #NP(selector+EXT);
|
|
IF code segment is non-conforming AND DPL < CPL
|
|
THEN GOTO INTERRUPT-TO-INNER-PRIVILEGE;
|
|
ELSE
|
|
IF code segment is conforming OR code segment DPL = CPL
|
|
THEN GOTO INTERRUPT-TO-SAME-PRIVILEGE-LEVEL;
|
|
ELSE #GP(CS selector + EXT);
|
|
FI;
|
|
FI;
|
|
|
|
INTERRUPT-TO-INNER-PRIVILEGE:
|
|
Check selector and descriptor for new stack in current TSS;
|
|
Selector must be non-null, else #GP(EXT);
|
|
Selector index must be within its descriptor table limits
|
|
ELSE #TS(SS selector+EXT);
|
|
Selector's RPL must equal DPL of code segment, else #TS(SS
|
|
selector+EXT);
|
|
Stack segment DPL must equal DPL of code segment, else #TS(SS
|
|
selector+EXT);
|
|
Descriptor must indicate writable data segment, else #TS(SS
|
|
selector+EXT);
|
|
Segment must be present, else #SS(SS selector+EXT);
|
|
IF 32-bit gate
|
|
THEN New stack must have room for 20 bytes else #SS(0)
|
|
ELSE New stack must have room for 10 bytes else #SS(0)
|
|
FI;
|
|
Instruction pointer must be within CS segment boundaries else #GP(0);
|
|
Load new SS and eSP value from TSS;
|
|
IF 32-bit gate
|
|
THEN CS:EIP selector:offset from gate;
|
|
ELSE CS:IP selector:offset from gate;
|
|
FI;
|
|
Load CS descriptor into invisible portion of CS register;
|
|
Load SS descriptor into invisible portion of SS register;
|
|
IF 32-bit gate
|
|
THEN
|
|
Push (long pointer to old stack) (* 3 words padded to 4 *);
|
|
Push (EFLAGS);
|
|
Push (long pointer to return location) (* 3 words padded to 4*);
|
|
ELSE
|
|
Push (long pointer to old stack) (* 2 words *);
|
|
Push (FLAGS);
|
|
Push (long pointer to return location) (* 2 words *);
|
|
FI;
|
|
Set CPL to new code segment DPL;
|
|
Set RPL of CS to CPL;
|
|
IF interrupt gate THEN IF 0 (* interrupt flag to 0 (disabled) *); FI;
|
|
TF 0;
|
|
NT 0;
|
|
|
|
INTERRUPT-FROM-V86-MODE:
|
|
TempEFlags EFLAGS;
|
|
VM 0;
|
|
TF 0;
|
|
IF service through Interrupt Gate THEN IF 0;
|
|
TempSS SS;
|
|
TempESP ESP;
|
|
SS TSS.SS0; (* Change to level 0 stack segment *)
|
|
ESP TSS.ESP0; (* Change to level 0 stack pointer *)
|
|
Push(GS); (* padded to two words *)
|
|
Push(FS); (* padded to two words *)
|
|
Push(DS); (* padded to two words *)
|
|
Push(ES); (* padded to two words *)
|
|
GS 0;
|
|
FS 0;
|
|
DS 0;
|
|
ES 0;
|
|
Push(TempSS); (* padded to two words *)
|
|
Push(TempESP);
|
|
Push(TempEFlags);
|
|
Push(CS); (* padded to two words *)
|
|
Push(EIP);
|
|
CS:EIP selector:offset from interrupt gate;
|
|
(* Starts execution of new routine in 80386 Protected Mode *)
|
|
|
|
INTERRUPT-TO-SAME-PRIVILEGE-LEVEL:
|
|
IF 32-bit gate
|
|
THEN Current stack limits must allow pushing 10 bytes, else #SS(0);
|
|
ELSE Current stack limits must allow pushing 6 bytes, else #SS(0);
|
|
FI;
|
|
IF interrupt was caused by exception with error code
|
|
THEN Stack limits must allow push of two more bytes;
|
|
ELSE #SS(0);
|
|
FI;
|
|
Instruction pointer must be in CS limit, else #GP(0);
|
|
IF 32-bit gate
|
|
THEN
|
|
Push (EFLAGS);
|
|
Push (long pointer to return location); (* 3 words padded to 4 *)
|
|
CS:EIP selector:offset from gate;
|
|
ELSE (* 16-bit gate *)
|
|
Push (FLAGS);
|
|
Push (long pointer to return location); (* 2 words *)
|
|
CS:IP selector:offset from gate;
|
|
FI;
|
|
Load CS descriptor into invisible portion of CS register;
|
|
Set the RPL field of CS to CPL;
|
|
Push (error code); (* if any *)
|
|
IF interrupt gate THEN IF 0; FI;
|
|
TF 0;
|
|
NT 0;
|
|
|
|
TASK-GATE:
|
|
Examine selector to TSS, given in task gate descriptor;
|
|
Must specify global in the local/global bit, else #TS(TSS selector);
|
|
Index must be within GDT limits, else #TS(TSS selector);
|
|
AR byte must specify available TSS (bottom bits 00001),
|
|
else #TS(TSS selector;
|
|
TSS must be present, else #NP(TSS selector);
|
|
SWITCH-TASKS with nesting to TSS;
|
|
IF interrupt was caused by fault with error code
|
|
THEN
|
|
Stack limits must allow push of two more bytes, else #SS(0);
|
|
Push error code onto stack;
|
|
FI;
|
|
Instruction pointer must be in CS limit, else #GP(0);
|
|
|
|
Description
|
|
|
|
The INT instruction generates via software a call to an interrupt
|
|
handler. The immediate operand, from 0 to 255, gives the index number
|
|
into the Interrupt Descriptor Table (IDT) of the interrupt routine to be
|
|
called. In Protected Mode, the IDT consists of an array of eight-byte
|
|
descriptors; the descriptor for the interrupt invoked must indicate an
|
|
interrupt, trap, or task gate. In Real Address Mode, the IDT is an array
|
|
of four byte-long pointers. In Protected and Real Address Modes, the
|
|
base linear address of the IDT is defined by the contents of the IDTR.
|
|
|
|
The INTO conditional software instruction is identical to the INT
|
|
interrupt instruction except that the interrupt number is implicitly 4,
|
|
and the interrupt is made only if the 80386 overflow flag is set.
|
|
|
|
The first 32 interrupts are reserved by Intel for system use. Some of
|
|
these interrupts are use for internally generated exceptions.
|
|
|
|
INT n generally behaves like a far call except that the flags register is
|
|
pushed onto the stack before the return address. Interrupt procedures
|
|
return via the IRET instruction, which pops the flags and return address
|
|
from the stack.
|
|
|
|
In Real Address Mode, INT n pushes the flags, CS, and the return IP
|
|
onto the stack, in that order, then jumps to the long pointer indexed by
|
|
the interrupt number.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP, #NP, #SS, and #TS as indicated under "Operation" above
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
None; if the SP or ESP = 1, 3, or 5 before executing INT or INTO,
|
|
the 80386 will shut down due to insufficient stack space
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
#GP(0) fault if IOPL is less than 3, for INT only, to permit emulation;
|
|
Interrupt 3 (0CCH) generates Interrupt 3; INTO generates Interrupt 4
|
|
if the overflow flag equals 1
|
|
|
|
|
|
IRET/IRETD ÄÄ Interrupt Return
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
CF IRET 22,pm=38 Interrupt return (far return and pop
|
|
flags)
|
|
CF IRET pm=82 Interrupt return to lesser privilege
|
|
CF IRET ts Interrupt return, different task (NT = 1)
|
|
CF IRETD 22,pm=38 Interrupt return (far return and pop
|
|
flags)
|
|
CF IRETD pm=82 Interrupt return to lesser privilege
|
|
CF IRETD pm=60 Interrupt return to V86 mode
|
|
CF IRETD ts Interrupt return, different task (NT = 1)
|
|
|
|
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
NOTE:
|
|
Values of ts are given by the following table:
|
|
|
|
New Task
|
|
|
|
Old Task 386 TSS 386 TSS 286 TSS
|
|
VM = 0 VM = 1
|
|
|
|
386
|
|
TSS VM=0 275 224 271
|
|
|
|
286
|
|
TSS 265 214 232
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
|
|
Operation
|
|
|
|
IF PE = 0
|
|
THEN (* Real-address mode *)
|
|
IF OperandSize = 32 (* Instruction = IRETD *)
|
|
THEN EIP Pop();
|
|
ELSE (* Instruction = IRET *)
|
|
IP Pop();
|
|
FI;
|
|
CS Pop();
|
|
IF OperandSize = 32 (* Instruction = IRETD *)
|
|
THEN EFLAGS Pop();
|
|
ELSE (* Instruction = IRET *)
|
|
FLAGS Pop();
|
|
FI;
|
|
ELSE (* Protected mode *)
|
|
IF VM = 1
|
|
THEN #GP(0);
|
|
ELSE
|
|
IF NT = 1
|
|
THEN GOTO TASK-RETURN;
|
|
ELSE
|
|
IF VM = 1 in flags image on stack
|
|
THEN GO TO STACK-RETURN-TO-V86;
|
|
ELSE GOTO STACK-RETURN;
|
|
FI;
|
|
FI;
|
|
FI;
|
|
FI;STACK-RETURN-TO-V86: (* Interrupted procedure was in V86 mode *)
|
|
IF return CS selector RPL < > 3
|
|
THEN #GP(Return selector);
|
|
FI;
|
|
IF top 36 bytes of stack not within limits
|
|
THEN #SS(0);
|
|
FI;
|
|
Examine return CS selector and associated descriptor:
|
|
IF selector is null, THEN #GP(0); FI;
|
|
IF selector index not within its descriptor table limits;
|
|
THEN #GP(Return selector);
|
|
FI;
|
|
IF AR byte does not indicate code segment
|
|
THEN #GP(Return selector);
|
|
FI;
|
|
IF code segment DPL not = 3;
|
|
THEN #GP(Return selector);
|
|
FI;
|
|
IF code segment not present
|
|
THEN #NP(Return selector);
|
|
FI;
|
|
|
|
Examine return SS selector and associated descriptor:
|
|
IF selector is null THEN #GP(0); FI;
|
|
IF selector index not within its descriptor table limits
|
|
THEN #GP(SS selector);
|
|
FI;
|
|
IF selector RPL not = RPL of return CS selector
|
|
THEN #GP(SS selector);
|
|
FI;
|
|
IF AR byte does not indicate a writable data segment
|
|
THEN #GP(SS selector);
|
|
FI;
|
|
IF stack segment DPL not = RPL of return CS selector
|
|
THEN #GP(SS selector);
|
|
FI;
|
|
IF SS not present
|
|
THEN #NP(SS selector);
|
|
FI;
|
|
|
|
IF instruction pointer not within code segment limit THEN #GP(0);
|
|
FI;
|
|
EFLAGS SS:[eSP + 8]; (* Sets VM in interrupted routine *)
|
|
EIP Pop();
|
|
CS Pop(); (* CS behaves as in 8086, due to VM = 1 *)
|
|
throwaway Pop(); (* pop away EFLAGS already read *)
|
|
ES Pop(); (* pop 2 words; throw away high-order word *)
|
|
DS Pop(); (* pop 2 words; throw away high-order word *)
|
|
FS Pop(); (* pop 2 words; throw away high-order word *)
|
|
GS Pop(); (* pop 2 words; throw away high-order word *)
|
|
IF CS.RPL > CPL
|
|
THEN
|
|
TempESP Pop();
|
|
TempSS Pop();
|
|
SS:ESP TempSS:TempESP;
|
|
FI;
|
|
|
|
(* Resume execution in Virtual 8086 mode *)
|
|
|
|
TASK-RETURN:
|
|
Examine Back Link Selector in TSS addressed by the current task
|
|
register:
|
|
Must specify global in the local/global bit, else #TS(new TSS
|
|
selector);
|
|
Index must be within GDT limits, else #TS(new TSS selector);
|
|
AR byte must specify TSS, else #TS(new TSS selector);
|
|
New TSS must be busy, else #TS(new TSS selector);
|
|
TSS must be present, else #NP(new TSS selector);
|
|
SWITCH-TASKS without nesting to TSS specified by back link selector;
|
|
Mark the task just abandoned as NOT BUSY;
|
|
Instruction pointer must be within code segment limit ELSE #GP(0);
|
|
|
|
STACK-RETURN:
|
|
IF OperandSize=32
|
|
THEN Third word on stack must be within stack limits, else #SS(0);
|
|
ELSE Second word on stack must be within stack limits, else #SS(0);
|
|
FI;
|
|
Return CS selector RPL must be ò CPL, else #GP(Return selector);
|
|
IF return selector RPL = CPL
|
|
THEN GOTO RETURN-SAME-LEVEL;
|
|
ELSE GOTO RETURN-OUTER-LEVEL;
|
|
FI;
|
|
|
|
RETURN-SAME-LEVEL:
|
|
IF OperandSize=32
|
|
THEN
|
|
Top 12 bytes on stack must be within limits, else #SS(0);
|
|
Return CS selector (at eSP+4) must be non-null, else #GP(0);
|
|
ELSE
|
|
Top 6 bytes on stack must be within limits, else #SS(0);
|
|
Return CS selector (at eSP+2) must be non-null, else #GP(0);
|
|
FI;
|
|
Selector index must be within its descriptor table limits, else #GP
|
|
(Return selector);
|
|
AR byte must indicate code segment, else #GP(Return selector);
|
|
IF non-conforming
|
|
THEN code segment DPL must = CPL;
|
|
ELSE #GP(Return selector);
|
|
FI;
|
|
IF conforming
|
|
THEN code segment DPL must be ó CPL, else #GP(Return selector);
|
|
Segment must be present, else #NP(Return selector);
|
|
Instruction pointer must be within code segment boundaries, else #GP(0);
|
|
FI;
|
|
IF OperandSize=32
|
|
THEN
|
|
Load CS:EIP from stack;
|
|
Load CS-register with new code segment descriptor;
|
|
Load EFLAGS with third doubleword from stack;
|
|
Increment eSP by 12;
|
|
ELSE
|
|
Load CS-register with new code segment descriptor;
|
|
Load FLAGS with third word on stack;
|
|
Increment eSP by 6;
|
|
FI;
|
|
|
|
RETURN-OUTER-LEVEL:
|
|
IF OperandSize=32
|
|
THEN Top 20 bytes on stack must be within limits, else #SS(0);
|
|
ELSE Top 10 bytes on stack must be within limits, else #SS(0);
|
|
FI;
|
|
Examine return CS selector and associated descriptor:
|
|
Selector must be non-null, else #GP(0);
|
|
Selector index must be within its descriptor table limits;
|
|
ELSE #GP(Return selector);
|
|
AR byte must indicate code segment, else #GP(Return selector);
|
|
IF non-conforming
|
|
THEN code segment DPL must = CS selector RPL;
|
|
ELSE #GP(Return selector);
|
|
FI;
|
|
IF conforming
|
|
THEN code segment DPL must be > CPL;
|
|
ELSE #GP(Return selector);
|
|
FI;
|
|
Segment must be present, else #NP(Return selector);
|
|
Examine return SS selector and associated descriptor:
|
|
Selector must be non-null, else #GP(0);
|
|
Selector index must be within its descriptor table limits
|
|
ELSE #GP(SS selector);
|
|
Selector RPL must equal the RPL of the return CS selector
|
|
ELSE #GP(SS selector);
|
|
AR byte must indicate a writable data segment, else #GP(SS selector);
|
|
Stack segment DPL must equal the RPL of the return CS selector
|
|
ELSE #GP(SS selector);
|
|
SS must be present, else #NP(SS selector);
|
|
|
|
Instruction pointer must be within code segment limit ELSE #GP(0);
|
|
IF OperandSize=32
|
|
THEN
|
|
Load CS:EIP from stack;
|
|
Load EFLAGS with values at (eSP+8);
|
|
ELSE
|
|
Load CS:IP from stack;
|
|
Load FLAGS with values at (eSP+4);
|
|
FI;
|
|
Load SS:eSP from stack;
|
|
Set CPL to the RPL of the return CS selector;
|
|
Load the CS register with the CS descriptor;
|
|
Load the SS register with the SS descriptor;
|
|
FOR each of ES, FS, GS, and DS
|
|
DO;
|
|
IF the current value of the register is not valid for the outer level;
|
|
THEN zero the register and clear the valid flag;
|
|
FI;
|
|
To be valid, the register setting must satisfy the following
|
|
properties:
|
|
Selector index must be within descriptor table limits;
|
|
AR byte must indicate data or readable code segment;
|
|
IF segment is data or non-conforming code,
|
|
THEN DPL must be ò CPL, or DPL must be ò RPL;
|
|
OD;
|
|
|
|
Description
|
|
|
|
In Real Address Mode, IRET pops the instruction pointer, CS, and the
|
|
flags register from the stack and resumes the interrupted routine.
|
|
|
|
In Protected Mode, the action of IRET depends on the setting of the
|
|
nested task flag (NT) bit in the flag register. When popping the new
|
|
flag image from the stack, the IOPL bits in the flag register are changed
|
|
only when CPL equals 0.
|
|
|
|
If NT equals 0, IRET returns from an interrupt procedure without a
|
|
task switch. The code returned to must be equally or less privileged than
|
|
the interrupt routine (as indicated by the RPL bits of the CS selector
|
|
popped from the stack). If the destination code is less privileged, IRET
|
|
also pops the stack pointer and SS from the stack.
|
|
|
|
If NT equals 1, IRET reverses the operation of a CALL or INT that
|
|
caused a task switch. The updated state of the task executing IRET is
|
|
saved in its task state segment. If the task is reentered later, the code
|
|
that follows IRET is executed.
|
|
|
|
Flags Affected
|
|
|
|
All; the flags register is popped from stack
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP, #NP, or #SS, as indicated under "Operation" above
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand being popped lies beyond address
|
|
0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
#GP(0) fault if IOPL is less than 3, to permit emulation
|
|
|
|
|
|
Jcc ÄÄ Jump if Condition is Met
|
|
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
77 cb JA rel8 7+m,3 Jump short if above (CF=0 and
|
|
ZF=0)
|
|
73 cb JAE rel8 7+m,3 Jump short if above or equal
|
|
(CF=0)
|
|
72 cb JB rel8 7+m,3 Jump short if below (CF=1)
|
|
76 cb JBE rel8 7+m,3 Jump short if below or equal
|
|
(CF=1 or ZF=1)
|
|
72 cb JC rel8 7+m,3 Jump short if carry (CF=1)
|
|
E3 cb JCXZ rel8 9+m,5 Jump short if CX register is 0
|
|
E3 cb JECXZ rel8 9+m,5 Jump short if ECX register is 0
|
|
74 cb JE rel8 7+m,3 Jump short if equal (ZF=1)
|
|
74 cb JZ rel8 7+m,3 Jump short if 0 (ZF=1)
|
|
7F cb JG rel8 7+m,3 Jump short if greater (ZF=0 and
|
|
SF=OF)
|
|
7D cb JGE rel8 7+m,3 Jump short if greater or equal
|
|
(SF=OF)
|
|
7C cb JL rel8 7+m,3 Jump short if less (SF<>OF)
|
|
7E cb JLE rel8 7+m,3 Jump short if less or equal
|
|
(ZF=1 and SF<>OF)
|
|
76 cb JNA rel8 7+m,3 Jump short if not above (CF=1 or
|
|
ZF=1)
|
|
72 cb JNAE rel8 7+m,3 Jump short if not above or equal
|
|
(CF=1)
|
|
73 cb JNB rel8 7+m,3 Jump short if not below (CF=0)
|
|
77 cb JNBE rel8 7+m,3 Jump short if not below or equal
|
|
(CF=0 and ZF=0)
|
|
73 cb JNC rel8 7+m,3 Jump short if not carry (CF=0)
|
|
75 cb JNE rel8 7+m,3 Jump short if not equal (ZF=0)
|
|
7E cb JNG rel8 7+m,3 Jump short if not greater (ZF=1
|
|
or SF<>OF)
|
|
7C cb JNGE rel8 7+m,3 Jump short if not greater or
|
|
equal (SF<>OF)
|
|
7D cb JNL rel8 7+m,3 Jump short if not less (SF=OF)
|
|
7F cb JNLE rel8 7+m,3 Jump short if not less or equal
|
|
(ZF=0 and SF=OF)
|
|
71 cb JNO rel8 7+m,3 Jump short if not overflow
|
|
(OF=0)
|
|
7B cb JNP rel8 7+m,3 Jump short if not parity (PF=0)
|
|
79 cb JNS rel8 7+m,3 Jump short if not sign (SF=0)
|
|
75 cb JNZ rel8 7+m,3 Jump short if not zero (ZF=0)
|
|
70 cb JO rel8 7+m,3 Jump short if overflow (OF=1)
|
|
7A cb JP rel8 7+m,3 Jump short if parity (PF=1)
|
|
7A cb JPE rel8 7+m,3 Jump short if parity even (PF=1)
|
|
7B cb JPO rel8 7+m,3 Jump short if parity odd (PF=0)
|
|
78 cb JS rel8 7+m,3 Jump short if sign (SF=1)
|
|
74 cb JZ rel8 7+m,3 Jump short if zero (ZF = 1)
|
|
0F 87 cw/cd JA rel16/32 7+m,3 Jump near if above (CF=0 and
|
|
ZF=0)
|
|
0F 83 cw/cd JAE rel16/32 7+m,3 Jump near if above or equal
|
|
(CF=0)
|
|
0F 82 cw/cd JB rel16/32 7+m,3 Jump near if below (CF=1)
|
|
0F 86 cw/cd JBE rel16/32 7+m,3 Jump near if below or equal
|
|
(CF=1 or ZF=1)
|
|
0F 82 cw/cd JC rel16/32 7+m,3 Jump near if carry (CF=1)
|
|
0F 84 cw/cd JE rel16/32 7+m,3 Jump near if equal (ZF=1)
|
|
0F 84 cw/cd JZ rel16/32 7+m,3 Jump near if 0 (ZF=1)
|
|
0F 8F cw/cd JG rel16/32 7+m,3 Jump near if greater (ZF=0 and
|
|
SF=OF)
|
|
0F 8D cw/cd JGE rel16/32 7+m,3 Jump near if greater or equal
|
|
(SF=OF)
|
|
0F 8C cw/cd JL rel16/32 7+m,3 Jump near if less (SF<>OF)
|
|
0F 8E cw/cd JLE rel16/32 7+m,3 Jump near if less or equal (ZF=1
|
|
and SF<>OF)
|
|
0F 86 cw/cd JNA rel16/32 7+m,3 Jump near if not above (CF=1 or
|
|
ZF=1)
|
|
0F 82 cw/cd JNAE rel16/32 7+m,3 Jump near if not above or equal
|
|
(CF=1)
|
|
0F 83 cw/cd JNB rel16/32 7+m,3 Jump near if not below (CF=0)
|
|
0F 87 cw/cd JNBE rel16/32 7+m,3 Jump near if not below or equal
|
|
(CF=0 and ZF=0)
|
|
0F 83 cw/cd JNC rel16/32 7+m,3 Jump near if not carry (CF=0)
|
|
0F 85 cw/cd JNE rel16/32 7+m,3 Jump near if not equal (ZF=0)
|
|
0F 8E cw/cd JNG rel16/32 7+m,3 Jump near if not greater (ZF=1
|
|
or SF<>OF)
|
|
0F 8C cw/cd JNGE rel16/32 7+m,3 Jump near if not greater or
|
|
equal (SF<>OF)
|
|
0F 8D cw/cd JNL rel16/32 7+m,3 Jump near if not less (SF=OF)
|
|
0F 8F cw/cd JNLE rel16/32 7+m,3 Jump near if not less or equal
|
|
(ZF=0 and SF=OF)
|
|
0F 81 cw/cd JNO rel16/32 7+m,3 Jump near if not overflow (OF=0)
|
|
0F 8B cw/cd JNP rel16/32 7+m,3 Jump near if not parity (PF=0)
|
|
0F 89 cw/cd JNS rel16/32 7+m,3 Jump near if not sign (SF=0)
|
|
0F 85 cw/cd JNZ rel16/32 7+m,3 Jump near if not zero (ZF=0)
|
|
0F 80 cw/cd JO rel16/32 7+m,3 Jump near if overflow (OF=1)
|
|
0F 8A cw/cd JP rel16/32 7+m,3 Jump near if parity (PF=1)
|
|
0F 8A cw/cd JPE rel16/32 7+m,3 Jump near if parity even (PF=1)
|
|
0F 8B cw/cd JPO rel16/32 7+m,3 Jump near if parity odd (PF=0)
|
|
0F 88 cw/cd JS rel16/32 7+m,3 Jump near if sign (SF=1)
|
|
0F 84 cw/cd JZ rel16/32 7+m,3 Jump near if 0 (ZF=1)
|
|
|
|
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
NOTES:
|
|
The first clock count is for the true condition (branch taken); the
|
|
second clock count is for the false condition (branch not taken). rel16/32
|
|
indicates that these instructions map to two; one with a 16-bit relative
|
|
displacement, the other with a 32-bit relative displacement, depending on
|
|
the operand-size attribute of the instruction.
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
|
|
Operation
|
|
|
|
IF condition
|
|
THEN
|
|
EIP EIP + SignExtend(rel8/16/32);
|
|
IF OperandSize = 16
|
|
THEN EIP EIP AND 0000FFFFH;
|
|
FI;
|
|
FI;
|
|
|
|
Description
|
|
|
|
Conditional jumps (except JCXZ) test the flags which have been set by
|
|
a previous instruction. The conditions for each mnemonic are given in
|
|
parentheses after each description above. The terms "less" and "greater"
|
|
are used for comparisons of signed integers; "above" and "below" are
|
|
used for unsigned integers.
|
|
|
|
If the given condition is true, a jump is made to the location provided as
|
|
the operand. Instruction coding is most efficient when the target for the
|
|
conditional jump is in the current code segment and within -128 to
|
|
+127 bytes of the next instruction's first byte. The jump can also target
|
|
-32768 thru +32767 (segment size attribute 16) or -2^(31) thru +2^(31) -1
|
|
(segment size attribute 32) relative to the next instruction's first byte.
|
|
When the target for the conditional jump is in a different segment, use
|
|
the opposite case of the jump instruction (i.e., JE and JNE), and then
|
|
access the target with an unconditional far jump to the other segment.
|
|
For example, you cannot codeÄÄ
|
|
|
|
JZ FARLABEL;
|
|
|
|
You must instead codeÄÄ
|
|
|
|
JNZ BEYOND;
|
|
JMP FARLABEL;
|
|
BEYOND:
|
|
|
|
Because there can be several ways to interpret a particular state of the
|
|
flags, ASM386 provides more than one mnemonic for most of the
|
|
conditional jump opcodes. For example, if you compared two characters in
|
|
AX and want to jump if they are equal, use JE; or, if you ANDed AX
|
|
with a bit field mask and only want to jump if the result is 0, use JZ, a
|
|
synonym for JE.
|
|
|
|
JCXZ differs from other conditional jumps because it tests the contents of
|
|
the CX or ECX register for 0, not the flags. JCXZ is useful at the beginning
|
|
of a conditional loop that terminates with a conditional loop instruction
|
|
(such as LOOPNE TARGET LABEL. The JCXZ prevents entering the loop with CX or
|
|
ECX equal to zero, which would cause the loop to execute 64K or 32G times
|
|
instead of zero times.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the offset jumped to is beyond the limits of the code segment
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
None
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
None
|
|
|
|
|
|
JMP ÄÄ Jump
|
|
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
EB cb JMP rel8 7+m Jump short
|
|
E9 cw JMP rel16 7+m Jump near, displacement relative
|
|
to next instruction
|
|
FF /4 JMP r/m16 7+m/10+m Jump near indirect
|
|
EA cd JMP ptr16:16 12+m,pm=27+m Jump intersegment, 4-byte
|
|
immediate address
|
|
EA cd JMP ptr16:16 pm=45+m Jump to call gate, same
|
|
privilege
|
|
EA cd JMP ptr16:16 ts Jump via task state segment
|
|
EA cd JMP ptr16:16 ts Jump via task gate
|
|
FF /5 JMP m16:16 43+m,pm=31+m Jump r/m16:16 indirect and
|
|
intersegment
|
|
FF /5 JMP m16:16 pm=49+m Jump to call gate, same
|
|
privilege
|
|
FF /5 JMP m16:16 5 + ts Jump via task state segment
|
|
FF /5 JMP m16:16 5 + ts Jump via task gate
|
|
E9 cd JMP rel32 7+m Jump near, displacement relative
|
|
to next instruction
|
|
FF /4 JMP r/m32 7+m,10+m Jump near, indirect
|
|
EA cp JMP ptr16:32 12+m,pm=27+m Jump intersegment, 6-byte
|
|
immediate address
|
|
EA cp JMP ptr16:32 pm=45+m Jump to call gate, same
|
|
privilege
|
|
EA cp JMP ptr16:32 ts Jump via task state segment
|
|
EA cp JMP ptr16:32 ts Jump via task gate
|
|
FF /5 JMP m16:32 43+m,pm=31+m Jump intersegment, address at
|
|
r/m dword
|
|
FF /5 JMP m16:32 pm=49+m Jump to call gate, same
|
|
privilege
|
|
FF /5 JMP m16:32 5 + ts Jump via task state segment
|
|
FF /5 JMP m16:32 5 + ts Jump via task gate
|
|
|
|
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
NOTE:
|
|
Values of ts are given by the following table:
|
|
|
|
New Task
|
|
|
|
386 TSS 386 TASK 286 TSS
|
|
VM = 0 VM = 1
|
|
|
|
Old Task Via Task Gate?
|
|
|
|
N Y N Y N Y
|
|
386
|
|
TSS VM=0 303 312 220 229 276 285
|
|
|
|
286
|
|
TSS 301 310 218 227 274 283
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
|
|
Operation
|
|
|
|
IF instruction = relative JMP
|
|
(* i.e. operand is rel8, rel16, or rel32 *)
|
|
THEN
|
|
EIP EIP + rel8/16/32;
|
|
IF OperandSize = 16
|
|
THEN EIP EIP AND 0000FFFFH;
|
|
FI;
|
|
FI;
|
|
IF instruction = near indirect JMP
|
|
(* i.e. operand is r/m16 or r/m32 *)
|
|
THEN
|
|
IF OperandSize = 16
|
|
THEN
|
|
EIP [r/m16] AND 0000FFFFH;
|
|
ELSE (* OperandSize = 32 *)
|
|
EIP [r/m32];
|
|
FI;
|
|
FI;
|
|
|
|
IF (PE = 0 OR (PE = 1 AND VM = 1)) (* real mode or V86 mode *)
|
|
AND instruction = far JMP
|
|
(* i.e., operand type is m16:16, m16:32, ptr16:16, ptr16:32 *)
|
|
THEN GOTO REAL-OR-V86-MODE;
|
|
IF operand type = m16:16 or m16:32
|
|
THEN (* indirect *)
|
|
IF OperandSize = 16
|
|
THEN
|
|
CS:IP [m16:16];
|
|
EIP EIP AND 0000FFFFH; (* clear upper 16 bits *)
|
|
ELSE (* OperandSize = 32 *)
|
|
CS:EIP [m16:32];
|
|
FI;
|
|
FI;
|
|
IF operand type = ptr16:16 or ptr16:32
|
|
THEN
|
|
IF OperandSize = 16
|
|
THEN
|
|
CS:IP ptr16:16;
|
|
EIP EIP AND 0000FFFFH; (* clear upper 16 bits *)
|
|
ELSE (* OperandSize = 32 *)
|
|
CS:EIP ptr16:32;
|
|
FI;
|
|
FI;
|
|
FI;
|
|
|
|
IF (PE = 1 AND VM = 0) (* Protected mode, not V86 mode *)
|
|
AND instruction = far JMP
|
|
THEN
|
|
IF operand type = m16:16 or m16:32
|
|
THEN (* indirect *)
|
|
check access of EA dword;
|
|
#GP(0) or #SS(0) IF limit violation;
|
|
FI;
|
|
Destination selector is not null ELSE #GP(0)
|
|
Destination selector index is within its descriptor table limits ELSE
|
|
#GP(selector)
|
|
Depending on AR byte of destination descriptor:
|
|
GOTO CONFORMING-CODE-SEGMENT;
|
|
GOTO NONCONFORMING-CODE-SEGMENT;
|
|
GOTO CALL-GATE;
|
|
GOTO TASK-GATE;
|
|
GOTO TASK-STATE-SEGMENT;
|
|
ELSE #GP(selector); (* illegal AR byte in descriptor *)
|
|
FI;
|
|
|
|
CONFORMING-CODE-SEGMENT:
|
|
Descriptor DPL must be ó CPL ELSE #GP(selector);
|
|
Segment must be present ELSE #NP(selector);
|
|
Instruction pointer must be within code-segment limit ELSE #GP(0);
|
|
IF OperandSize = 32
|
|
THEN Load CS:EIP from destination pointer;
|
|
ELSE Load CS:IP from destination pointer;
|
|
FI;
|
|
Load CS register with new segment descriptor;
|
|
|
|
NONCONFORMING-CODE-SEGMENT:
|
|
RPL of destination selector must be ó CPL ELSE #GP(selector);
|
|
Descriptor DPL must be = CPL ELSE #GP(selector);
|
|
Segment must be present ELSE # NP(selector);
|
|
Instruction pointer must be within code-segment limit ELSE #GP(0);
|
|
IF OperandSize = 32
|
|
THEN Load CS:EIP from destination pointer;
|
|
ELSE Load CS:IP from destination pointer;
|
|
FI;
|
|
Load CS register with new segment descriptor;
|
|
Set RPL field of CS register to CPL;
|
|
|
|
CALL-GATE:
|
|
Descriptor DPL must be ò CPL ELSE #GP(gate selector);
|
|
Descriptor DPL must be ò gate selector RPL ELSE #GP(gate selector);
|
|
Gate must be present ELSE #NP(gate selector);
|
|
Examine selector to code segment given in call gate descriptor:
|
|
Selector must not be null ELSE #GP(0);
|
|
Selector must be within its descriptor table limits ELSE
|
|
#GP(CS selector);
|
|
Descriptor AR byte must indicate code segment
|
|
ELSE #GP(CS selector);
|
|
IF non-conforming
|
|
THEN code-segment descriptor, DPL must = CPL
|
|
ELSE #GP(CS selector);
|
|
FI;
|
|
IF conforming
|
|
THEN code-segment descriptor DPL must be ó CPL;
|
|
ELSE #GP(CS selector);
|
|
Code segment must be present ELSE #NP(CS selector);
|
|
Instruction pointer must be within code-segment limit ELSE #GP(0);
|
|
IF OperandSize = 32
|
|
THEN Load CS:EIP from call gate;
|
|
ELSE Load CS:IP from call gate;
|
|
FI;
|
|
Load CS register with new code-segment descriptor;
|
|
Set RPL of CS to CPL
|
|
|
|
TASK-GATE:
|
|
Gate descriptor DPL must be ò CPL ELSE #GP(gate selector);
|
|
Gate descriptor DPL must be ò gate selector RPL ELSE #GP(gate
|
|
selector);
|
|
Task Gate must be present ELSE #NP(gate selector);
|
|
Examine selector to TSS, given in Task Gate descriptor:
|
|
Must specify global in the local/global bit ELSE #GP(TSS selector);
|
|
Index must be within GDT limits ELSE #GP(TSS selector);
|
|
Descriptor AR byte must specify available TSS (bottom bits 00001);
|
|
ELSE #GP(TSS selector);
|
|
Task State Segment must be present ELSE #NP(TSS selector);
|
|
SWITCH-TASKS (without nesting) to TSS;
|
|
Instruction pointer must be within code-segment limit ELSE #GP(0);
|
|
|
|
TASK-STATE-SEGMENT:
|
|
TSS DPL must be ò CPL ELSE #GP(TSS selector);
|
|
TSS DPL must be ò TSS selector RPL ELSE #GP(TSS selector);
|
|
Descriptor AR byte must specify available TSS (bottom bits 00001)
|
|
ELSE #GP(TSS selector);
|
|
Task State Segment must be present ELSE #NP(TSS selector);
|
|
SWITCH-TASKS (without nesting) to TSS;
|
|
Instruction pointer must be within code-segment limit ELSE #GP(0);
|
|
|
|
Description
|
|
|
|
The JMP instruction transfers control to a different point in the
|
|
instruction stream without recording return information.
|
|
|
|
The action of the various forms of the instruction are shown below.
|
|
|
|
Jumps with destinations of type r/m16, r/m32, rel16, and rel32 are near
|
|
jumps and do not involve changing the segment register value.
|
|
|
|
The JMP rel16 and JMP rel32 forms of the instruction add an offset to
|
|
the address of the instruction following the JMP to determine the
|
|
destination. The rel16 form is used when the instruction's operand-size
|
|
attribute is 16 bits (segment size attribute 16 only); rel32 is used when
|
|
the operand-size attribute is 32 bits (segment size attribute 32 only). The
|
|
result is stored in the 32-bit EIP register. With rel16, the upper 16 bits
|
|
of EIP are cleared, which results in an offset whose value does not exceed
|
|
16 bits.
|
|
|
|
JMP r/m16 and JMP r/m32 specifies a register or memory location from which
|
|
the absolute offset from the procedure is fetched. The offset fetched from
|
|
r/m is 32 bits for an operand-size attribute of 32 bits (r/m32), or 16 bits
|
|
for an operand-size attribute of 16 bits (r/m16).
|
|
|
|
The JMP ptr16:16 and ptr16:32 forms of the instruction use a four-byte
|
|
or six-byte operand as a long pointer to the destination. The JMP
|
|
and forms fetch the long pointer from the memory location
|
|
specified (indirection). In Real Address Mode or Virtual 8086 Mode,
|
|
the long pointer provides 16 bits for the CS register and 16 or 32 bits
|
|
for the EIP register (depending on the operand-size attribute). In
|
|
Protected Mode, both long pointer forms consult the Access Rights (AR)
|
|
byte in the descriptor indexed by the selector part of the long pointer.
|
|
|
|
Depending on the value of the AR byte, the jump will perform one of
|
|
the following types of control transfers:
|
|
|
|
þ A jump to a code segment at the same privilege level
|
|
þ A task switch
|
|
|
|
For more information on protected mode control transfers, refer to
|
|
Chapter 6 and Chapter 7.
|
|
|
|
Flags Affected
|
|
|
|
All if a task switch takes place; none if no task switch occurs
|
|
|
|
Protected Mode Exceptions
|
|
|
|
Far jumps: #GP, #NP, #SS, and #TS, as indicated in the list above.
|
|
|
|
Near direct jumps: #GP(0) if procedure location is beyond the code
|
|
segment limits.
|
|
|
|
Near indirect jumps: #GP(0) for an illegal memory operand effective
|
|
address in the CS, DS, ES, FS, or GS segments: #SS(0) for an illegal
|
|
address in the SS segment; #GP if the indirect offset obtained is beyond
|
|
the code segment limits; #PF(fault-code) for a page fault.
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would be outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as under Real Address Mode; #PF(fault-code) for a
|
|
page fault
|
|
|
|
|
|
LAHF ÄÄ Load Flags into AH Register
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
9F LAHF 2 Load: AH = flags SF ZF xx AF xx PF xx CF
|
|
|
|
|
|
Operation
|
|
|
|
AH SF:ZF:xx:AF:xx:PF:xx:CF;
|
|
|
|
Description
|
|
|
|
LAHF transfers the low byte of the flags word to AH. The bits, from
|
|
MSB to LSB, are sign, zero, indeterminate, auxiliary, carry,
|
|
indeterminate, parity, indeterminate, and carry.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
None
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
None
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
None
|
|
|
|
|
|
LAR ÄÄ Load Access Rights Byte
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
0F 02 /r LAR r16,r/m16 pm=15/16 r16 r/m16 masked by FF00
|
|
0F 02 /r LAR r32,r/m32 pm=15/16 r32 r/m32 masked by 00FxFF00
|
|
|
|
|
|
Description
|
|
|
|
The LAR instruction stores a marked form of the second doubleword of
|
|
the descriptor for the source selector if the selector is visible at the
|
|
CPL (modified by the selector's RPL) and is a valid descriptor type. The
|
|
destination register is loaded with the high-order doubleword of the
|
|
descriptor masked by 00FxFF00, and ZF is set to 1. The x indicates that the
|
|
four bits corresponding to the upper four bits of the limit are undefined in
|
|
the value loaded by LAR. If the selector is invisible or of the wrong type,
|
|
ZF is cleared.
|
|
|
|
If the 32-bit operand size is specified, the entire 32-bit value is loaded
|
|
into the 32-bit destination register. If the 16-bit operand size is
|
|
specified, the lower 16-bits of this value are stored in the 16-bit
|
|
destination register.
|
|
|
|
All code and data segment descriptors are valid for LAR.
|
|
|
|
The valid special segment and gate descriptor types for LAR are given
|
|
in the following table:
|
|
|
|
Type Name Valid/Invalid
|
|
|
|
0 Invalid Invalid
|
|
1 Available 80286 TSS Valid
|
|
2 LDT Valid
|
|
3 Busy 80286 TSS Valid
|
|
4 80286 call gate Valid
|
|
5 80286/80386 task gate Valid
|
|
6 80286 trap gate Valid
|
|
7 80286 interrupt gate Valid
|
|
8 Invalid Invalid
|
|
9 Available 80386 TSS Valid
|
|
A Invalid Invalid
|
|
B Busy 80386 TSS Valid
|
|
C 80386 call gate Valid
|
|
D Invalid Invalid
|
|
E 80386 trap gate Valid
|
|
F 80386 interrupt gate Valid
|
|
|
|
Flags Affected
|
|
|
|
ZF as described above
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) for an illegal memory operand effective address in the CS, DS,
|
|
ES, FS, or GS segments; #SS(0) for an illegal address in the SS segment;
|
|
#PF(fault-code) for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 6; LAR is unrecognized in Real Address Mode
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode
|
|
|
|
|
|
LEA ÄÄ Load Effective Address
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
8D /r LEA r16,m 2 Store effective address for m in register r16
|
|
8D /r LEA r32,m 2 Store effective address for m in register r32
|
|
8D /r LEA r16,m 2 Store effective address for m in register r16
|
|
8D /r LEA r32,m 2 Store effective address for m in register r32
|
|
|
|
|
|
Operation
|
|
|
|
IF OperandSize = 16 AND AddressSize = 16
|
|
THEN r16 Addr(m);
|
|
ELSE
|
|
IF OperandSize = 16 AND AddressSize = 32
|
|
THEN
|
|
r16 Truncate_to_16bits(Addr(m)); (* 32-bit address *)
|
|
ELSE
|
|
IF OperandSize = 32 AND AddressSize = 16
|
|
THEN
|
|
r32 Truncate_to_16bits(Addr(m));
|
|
ELSE
|
|
IF OperandSize = 32 AND AddressSize = 32
|
|
THEN r32 Addr(m);
|
|
FI;
|
|
FI;
|
|
FI;
|
|
FI;
|
|
|
|
Description
|
|
|
|
LEA calculates the effective address (offset part) and stores it in the
|
|
specified register. The operand-size attribute of the instruction
|
|
(represented by OperandSize in the algorithm under "Operation" above) is
|
|
determined by the chosen register. The address-size attribute (represented
|
|
by AddressSize) is determined by the USE attribute of the segment containing
|
|
the second operand. The address-size and operand-size attributes affect the
|
|
action performed by LEA, as follows:
|
|
|
|
Operand Size Address Size Action Performed
|
|
|
|
16 16 16-bit effective address is calculated and
|
|
stored in requested 16-bit register
|
|
destination.
|
|
|
|
16 32 32-bit effective address is calculated. The
|
|
lower 16 bits of the address are stored in
|
|
the requested 16-bit register destination.
|
|
|
|
32 16 16-bit effective address is calculated. The
|
|
16-bit address is zero-extended and stored
|
|
in the requested 32-bit register destination.
|
|
|
|
32 32 32-bit effective address is calculated and
|
|
stored in the requested 32-bit register
|
|
destination.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#UD if the second operand is a register
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 6 if the second operand is a register
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode
|
|
|
|
|
|
LEAVE ÄÄ High Level Procedure Exit
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
C9 LEAVE 4 Set SP to BP, then pop BP
|
|
C9 LEAVE 4 Set ESP to EBP, then pop EBP
|
|
|
|
|
|
Operation
|
|
|
|
IF StackAddrSize = 16
|
|
THEN
|
|
SP BP;
|
|
ELSE (* StackAddrSize = 32 *)
|
|
ESP EBP;
|
|
FI;
|
|
IF OperandSize = 16
|
|
THEN
|
|
BP Pop();
|
|
ELSE (* OperandSize = 32 *)
|
|
EBP Pop();
|
|
FI;
|
|
|
|
Description
|
|
|
|
LEAVE reverses the actions of the ENTER instruction. By copying the
|
|
frame pointer to the stack pointer, LEAVE releases the stack space used
|
|
by a procedure for its local variables. The old frame pointer is popped
|
|
into BP or EBP, restoring the caller's frame. A subsequent RET
|
|
instruction removes any arguments pushed onto the stack of the exiting
|
|
procedure.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#SS(0) if BP does not point to a location within the limits of the current
|
|
stack segment
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode
|
|
|
|
|
|
LGDT/LIDT ÄÄ Load Global/Interrupt Descriptor Table Register
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
0F 01 /2 LGDT m16&32 11 Load m into GDTR
|
|
0F 01 /3 LIDT m16&32 11 Load m into IDTR
|
|
|
|
|
|
Operation
|
|
|
|
IF instruction = LIDT
|
|
THEN
|
|
IF OperandSize = 16
|
|
THEN IDTR.Limit:Base m16:24 (* 24 bits of base loaded *)
|
|
ELSE IDTR.Limit:Base m16:32
|
|
FI;
|
|
ELSE (* instruction = LGDT *)
|
|
IF OperandSize = 16
|
|
THEN GDTR.Limit:Base m16:24 (* 24 bits of base loaded *)
|
|
ELSE GDTR.Limit:Base m16:32;
|
|
FI;
|
|
FI;
|
|
|
|
Description
|
|
|
|
The LGDT and LIDT instructions load a linear base address and limit
|
|
value from a six-byte data operand in memory into the GDTR or IDTR,
|
|
respectively. If a 16-bit operand is used with LGDT or LIDT, the
|
|
register is loaded with a 16-bit limit and a 24-bit base, and the
|
|
high-order eight bits of the six-byte data operand are not used. If a 32-bit
|
|
operand is used, a 16-bit limit and a 32-bit base is loaded; the high-order
|
|
eight bits of the six-byte operand are used as high-order base address bits.
|
|
|
|
The SGDT and SIDT instructions always store into all 48 bits of the
|
|
six-byte data operand. With the 80286, the upper eight bits are undefined
|
|
after SGDT or SIDT is executed. With the 80386, the upper eight bits
|
|
are written with the high-order eight address bits, for both a 16-bit
|
|
operand and a 32-bit operand. If LGDT or LIDT is used with a 16-bit
|
|
operand to load the register stored by SGDT or SIDT, the upper eight
|
|
bits are stored as zeros.
|
|
|
|
LGDT and LIDT appear in operating system software; they are not used
|
|
in application programs. They are the only instructions that directly load
|
|
a linear address (i.e., not a segment relative address) in 80386 Protected
|
|
Mode.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the current privilege level is not 0; #UD if the source operand
|
|
is a register; #GP(0) for an illegal memory operand effective address in
|
|
the CS, DS, ES, FS, or GS segments; #SS(0) for an illegal address in
|
|
the SS segment; #PF(fault-code) for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH; Interrupt 6 if the source operand is a
|
|
register
|
|
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
Note:
|
|
These instructions are valid in Real Address Mode to allow
|
|
power-up initialization for Protected Mode
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
|
|
fault
|
|
|
|
|
|
LGS/LSS/LDS/LES/LFS ÄÄ Load Full Pointer
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
C5 /r LDS r16,m16:16 7,p=22 Load DS:r16 with pointer from memory
|
|
C5 /r LDS r32,m16:32 7,p=22 Load DS:r32 with pointer from memory
|
|
0F B2 /r LSS r16,m16:16 7,p=22 Load SS:r16 with pointer from memory
|
|
0F B2 /r LSS r32,m16:32 7,p=22 Load SS:r32 with pointer from memory
|
|
C4 /r LES r16,m16:16 7,p=22 Load ES:r16 with pointer from memory
|
|
C4 /r LES r32,m16:32 7,p=22 Load ES:r32 with pointer from memory
|
|
0F B4 /r LFS r16,m16:16 7,p=25 Load FS:r16 with pointer from memory
|
|
0F B4 /r LFS r32,m16:32 7,p=25 Load FS:r32 with pointer from memory
|
|
0F B5 /r LGS r16,m16:16 7,p=25 Load GS:r16 with pointer from memory
|
|
0F B5 /r LGS r32,m16:32 7,p=25 Load GS:r32 with pointer from memory
|
|
|
|
|
|
Operation
|
|
|
|
CASE instruction OF
|
|
LSS: Sreg is SS; (* Load SS register *)
|
|
LDS: Sreg is DS; (* Load DS register *)
|
|
LES: Sreg is ES; (* Load ES register *)
|
|
LFS: Sreg is FS; (* Load FS register *)
|
|
LGS: Sreg is DS; (* Load GS register *)
|
|
ESAC;
|
|
IF (OperandSize = 16)
|
|
THEN
|
|
r16 [Effective Address]; (* 16-bit transfer *)
|
|
Sreg [Effective Address + 2]; (* 16-bit transfer *)
|
|
(* In Protected Mode, load the descriptor into the segment register *)
|
|
ELSE (* OperandSize = 32 *)
|
|
r32 [Effective Address]; (* 32-bit transfer *)
|
|
Sreg [Effective Address + 4]; (* 16-bit transfer *)
|
|
(* In Protected Mode, load the descriptor into the segment register *)
|
|
FI;
|
|
|
|
Description
|
|
|
|
These instructions read a full pointer from memory and store it in the
|
|
selected segment register:register pair. The full pointer loads 16 bits
|
|
into the segment register SS, DS, ES, FS, or GS. The other register loads 32
|
|
bits if the operand-size attribute is 32 bits, or loads 16 bits if the
|
|
operand-size attribute is 16 bits. The other 16- or 32-bit register to be
|
|
loaded is determined by the r16 or r32 register operand specified.
|
|
|
|
When an assignment is made to one of the segment registers, the
|
|
descriptor is also loaded into the segment register. The data for the
|
|
register is obtained from the descriptor table entry for the selector
|
|
given.
|
|
|
|
A null selector (values 0000-0003) can be loaded into DS, ES, FS, or
|
|
GS registers without causing a protection exception. (Any subsequent
|
|
reference to a segment whose corresponding segment register is loaded
|
|
with a null selector to address memory causes a #GP(0) exception. No
|
|
memory reference to the segment occurs.)
|
|
|
|
The following is a listing of the Protected Mode checks and actions taken in
|
|
the loading of a segment register:
|
|
|
|
IF SS is loaded:
|
|
IF selector is null THEN #GP(0); FI;
|
|
Selector index must be within its descriptor table limits ELSE
|
|
#GP(selector);
|
|
Selector's RPL must equal CPL ELSE #GP(selector);
|
|
AR byte must indicate a writable data segment ELSE #GP(selector);
|
|
DPL in the AR byte must equal CPL ELSE #GP(selector);
|
|
Segment must be marked present ELSE #SS(selector);
|
|
Load SS with selector;
|
|
Load SS with descriptor;
|
|
IF DS, ES, FS, or GS is loaded with non-null selector:
|
|
Selector index must be within its descriptor table limits ELSE
|
|
#GP(selector);
|
|
AR byte must indicate data or readable code segment ELSE
|
|
#GP(selector);
|
|
IF data or nonconforming code
|
|
THEN both the RPL and the CPL must be less than or equal to DPL in
|
|
AR byte;
|
|
ELSE #GP(selector);
|
|
Segment must be marked present ELSE #NP(selector);
|
|
Load segment register with selector and RPL bits;
|
|
Load segment register with descriptor;
|
|
IF DS, ES, FS or GS is loaded with a null selector:
|
|
Clear descriptor valid bit;
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) for an illegal memory operand effective address in the CS, DS,
|
|
ES, FS, or GS segments; #SS(0) for an illegal address in the SS segment;
|
|
the second operand must be a memory operand, not a register; #GP(0)
|
|
if a null selector is loaded into SS; #PF(fault-code) for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
The second operand must be a memory operand, not a register; Interrupt
|
|
13 if any part of the operand would lie outside of the effective address
|
|
space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
|
|
fault
|
|
|
|
|
|
LLDT ÄÄ Load Local Descriptor Table Register
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
0F 00 /2 LLDT r/m16 20 Load selector r/m16 into LDTR
|
|
|
|
|
|
Operation
|
|
|
|
LDTR SRC;
|
|
|
|
Description
|
|
|
|
LLDT loads the Local Descriptor Table register (LDTR). The word
|
|
operand (memory or register) to LLDT should contain a selector to the
|
|
Global Descriptor Table (GDT). The GDT entry should be a Local Descriptor
|
|
Table. If so, then the LDTR is loaded from the entry. The descriptor
|
|
registers DS, ES, SS, FS, GS, and CS are not affected. The LDT field in the
|
|
task state segment does not change.
|
|
|
|
The selector operand can be 0; if so, the LDTR is marked invalid. All
|
|
descriptor references (except by the LAR, VERR, VERW or LSL
|
|
instructions) cause a #GP fault.
|
|
|
|
LLDT is used in operating system software; it is not used in application
|
|
programs.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the current privilege level is not 0; #GP(selector) if the
|
|
selector operand does not point into the Global Descriptor Table, or if the
|
|
entry in the GDT is not a Local Descriptor Table; #NP(selector) if the
|
|
LDT descriptor is not present; #GP(0) for an illegal memory operand
|
|
effective address in the CS, DS, ES, FS, or GS segments; #SS(0) for an
|
|
illegal address in the SS segment; #PF(fault-code) for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 6; LLDT is not recognized in Real Address Mode
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode (because the instruction is
|
|
not recognized, it will not execute or perform a memory reference)
|
|
|
|
Note
|
|
|
|
The operand-size attribute has no effect on this instruction.
|
|
|
|
|
|
LMSW ÄÄ Load Machine Status Word
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
0F 01 /6 LMSW r/m16 10/13 Load r/m16 in machine status word
|
|
|
|
|
|
Operation
|
|
|
|
MSW r/m16; (* 16 bits is stored in the machine status word *)
|
|
|
|
Description
|
|
|
|
LMSW loads the machine status word (part of CR0) from the source
|
|
operand. This instruction can be used to switch to Protected Mode; if so,
|
|
it must be followed by an intrasegment jump to flush the instruction
|
|
queue. LMSW will not switch back to Real Address Mode.
|
|
|
|
LMSW is used only in operating system software. It is not used in
|
|
application programs.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the current privilege level is not 0; #GP(0) for an illegal
|
|
memory operand effective address in the CS, DS, ES, FS, or GS
|
|
segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code)
|
|
for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
|
|
fault
|
|
|
|
Notes
|
|
|
|
The operand-size attribute has no effect on this instruction. This
|
|
instruction is provided for compatibility with the 80286; 80386 programs
|
|
should use MOV CR0, ... instead.
|
|
|
|
|
|
LOCK ÄÄ Assert LOCK# Signal Prefix
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
F0 LOCK 0 Assert LOCK# signal for the next instruction
|
|
|
|
|
|
Description
|
|
|
|
The LOCK prefix causes the LOCK# signal of the 80386 to be asserted
|
|
during execution of the instruction that follows it. In a multiprocessor
|
|
environment, this signal can be used to ensure that the 80386 has
|
|
exclusive use of any shared memory while LOCK# is asserted. The
|
|
read-modify-write sequence typically used to implement test-and-set on the
|
|
80386 is the BTS instruction.
|
|
|
|
The LOCK prefix functions only with the following instructions:
|
|
|
|
BT, BTS, BTR, BTC mem, reg/imm
|
|
XCHG reg, mem
|
|
XCHG mem, reg
|
|
ADD, OR, ADC, SBB, AND, SUB, XOR mem, reg/imm
|
|
NOT, NEG, INC, DEC mem
|
|
|
|
An undefined opcode trap will be generated if a LOCK prefix is used
|
|
with any instruction not listed above.
|
|
|
|
XCHG always asserts LOCK# regardless of the presence or absence of
|
|
the LOCK prefix.
|
|
|
|
The integrity of the LOCK is not affected by the alignment of the
|
|
memory field. Memory locking is observed for arbitrarily misaligned
|
|
fields.
|
|
|
|
Locked access is not assured if another 80386 processor is executing an
|
|
instruction concurrently that has one of the following characteristics:
|
|
|
|
þ Is not preceded by a LOCK prefix
|
|
|
|
þ Is not one of the instructions in the preceding list
|
|
|
|
þ Specifies a memory operand that does not exactly overlap the
|
|
destination operand. Locking is not guaranteed for partial overlap,
|
|
even if one memory operand is wholly contained within another.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#UD if LOCK is used with an instruction not listed in the "Description"
|
|
section above; other exceptions can be generated by the subsequent
|
|
(locked) instruction
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 6 if LOCK is used with an instruction not listed in the
|
|
"Description" section above; exceptions can still be generated by the
|
|
subsequent (locked) instruction
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
#UD if LOCK is used with an instruction not listed in the "Description"
|
|
section above; exceptions can still be generated by the subsequent (locked)
|
|
instruction
|
|
|
|
|
|
LODS/LODSB/LODSW/LODSD ÄÄ Load String Operand
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
AC LODS m8 5 Load byte [(E)SI] into AL
|
|
AD LODS m16 5 Load word [(E)SI] into AX
|
|
AD LODS m32 5 Load dword [(E)SI] into EAX
|
|
AC LODSB 5 Load byte DS:[(E)SI] into AL
|
|
AD LODSW 5 Load word DS:[(E)SI] into AX
|
|
AD LODSD 5 Load dword DS:[(E)SI] into EAX
|
|
|
|
|
|
Operation
|
|
|
|
IF AddressSize = 16
|
|
THEN use SI for source-index
|
|
ELSE (* AddressSize = 32 *)
|
|
use ESI for source-index;
|
|
FI;
|
|
IF byte type of instruction
|
|
THEN
|
|
AL [source-index]; (* byte load *)
|
|
IF DF = 0 THEN IncDec 1 ELSE IncDec -1; FI;
|
|
ELSE
|
|
IF OperandSize = 16
|
|
THEN
|
|
AX [source-index]; (* word load *)
|
|
IF DF = 0 THEN IncDec 2 ELSE IncDec -2; FI;
|
|
ELSE (* OperandSize = 32 *)
|
|
EAX [source-index]; (* dword load *)
|
|
IF DF = 0 THEN IncDec 4 ELSE IncDec -4; FI;
|
|
FI;
|
|
FI;
|
|
source-index source-index + IncDec
|
|
|
|
Description
|
|
|
|
LODS loads the AL, AX, or EAX register with the memory byte, word,
|
|
or doubleword at the location pointed to by the source-index register.
|
|
After the transfer is made, the source-index register is automatically
|
|
advanced. If the direction flag is 0 (CLD was executed), the source index
|
|
increments; if the direction flag is 1 (STD was executed), it decrements.
|
|
The increment or decrement is 1 if a byte is loaded, 2 if a word is loaded,
|
|
or 4 if a doubleword is loaded.
|
|
|
|
If the address-size attribute for this instruction is 16 bits, SI is used
|
|
for the source-index register; otherwise the address-size attribute is 32
|
|
bits, and the ESI register is used. The address of the source data is
|
|
determined solely by the contents of ESI/SI. Load the correct index value
|
|
into SI before executing the LODS instruction. LODSB, LODSW, LODSD are
|
|
synonyms for the byte, word, and doubleword LODS instructions.
|
|
|
|
LODS can be preceded by the REP prefix; however, LODS is used more typically
|
|
within a LOOP construct, because further processing of the data moved into
|
|
EAX, AX, or AL is usually necessary.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) for an illegal memory operand effective address in the CS, DS,
|
|
ES, FS, or GS segments; #SS(0) for an illegal address in the SS segment;
|
|
#PF(fault-code) for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
|
|
fault
|
|
|
|
|
|
LOOP/LOOPcond ÄÄ Loop Control with CX Counter
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
E2 cb LOOP rel8 11+m DEC count; jump short if count <> 0
|
|
E1 cb LOOPE rel8 11+m DEC count; jump short if count <> 0 and ZF=1
|
|
E1 cb LOOPZ rel8 11+m DEC count; jump short if count <> 0 and ZF=1
|
|
E0 cb LOOPNE rel8 11+m DEC count; jump short if count <> 0 and ZF=0
|
|
E0 cb LOOPNZ rel8 11+m DEC count; jump short if count <> 0 and ZF=0
|
|
|
|
|
|
Operation
|
|
|
|
IF AddressSize = 16 THEN CountReg is CX ELSE CountReg is ECX; FI;
|
|
CountReg CountReg - 1;
|
|
IF instruction <> LOOP
|
|
THEN
|
|
IF (instruction = LOOPE) OR (instruction = LOOPZ)
|
|
THEN BranchCond (ZF = 1) AND (CountReg <> 0);
|
|
FI;
|
|
IF (instruction = LOOPNE) OR (instruction = LOOPNZ)
|
|
THEN BranchCond (ZF = 0) AND (CountReg <> 0);
|
|
FI;
|
|
FI;
|
|
|
|
IF BranchCond
|
|
THEN
|
|
IF OperandSize = 16
|
|
THEN
|
|
IP IP + SignExtend(rel8);
|
|
ELSE (* OperandSize = 32 *)
|
|
EIP EIP + SignExtend(rel8);
|
|
FI;
|
|
FI;
|
|
|
|
Description
|
|
|
|
LOOP decrements the count register without changing any of the flags.
|
|
Conditions are then checked for the form of LOOP being used. If the
|
|
conditions are met, a short jump is made to the label given by the operand
|
|
to LOOP. If the address-size attribute is 16 bits, the CX register is used
|
|
as the count register; otherwise the ECX register is used. The operand
|
|
of LOOP must be in the range from 128 (decimal) bytes before the
|
|
instruction to 127 bytes ahead of the instruction.
|
|
|
|
The LOOP instructions provide iteration control and combine loop index
|
|
management with conditional branching. Use the LOOP instruction by
|
|
loading an unsigned iteration count into the count register, then code the
|
|
LOOP at the end of a series of instructions to be iterated. The
|
|
destination of LOOP is a label that points to the beginning of the
|
|
iteration.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the offset jumped to is beyond the limits of the current code
|
|
segment
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
None
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
None
|
|
|
|
|
|
LSL ÄÄ Load Segment Limit
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
0F 03 /r LSL r16,r/m16 pm=20/21 Load: r16 segment limit,
|
|
selector r/m16 (byte granular)
|
|
0F 03 /r LSL r32,r/m32 pm=20/21 Load: r32 segment limit,
|
|
selector r/m32 (byte granular)
|
|
0F 03 /r LSL r16,r/m16 pm=25/26 Load: r16 segment limit,
|
|
selector r/m16 (page granular)
|
|
0F 03 /r LSL r32,r/m32 pm=25/26 Load: r32 segment limit,
|
|
selector r/m32 (page granular)
|
|
|
|
|
|
Description
|
|
|
|
The LSL instruction loads a register with an unscrambled segment limit,
|
|
and sets ZF to 1, provided that the source selector is visible at the CPL
|
|
weakened by RPL, and that the descriptor is a type accepted by LSL.
|
|
Otherwise, ZF is cleared to 0, and the destination register is unchanged.
|
|
The segment limit is loaded as a byte granular value. If the descriptor
|
|
has a page granular segment limit, LSL will translate it to a byte limit
|
|
before loading it in the destination register (shift left 12 the 20-bit
|
|
"raw" limit from descriptor, then OR with 00000FFFH).
|
|
|
|
The 32-bit forms of this instruction store the 32-bit byte granular limit
|
|
in the 16-bit destination register.
|
|
|
|
Code and data segment descriptors are valid for LSL.
|
|
|
|
The valid special segment and gate descriptor types for LSL are given
|
|
in the following table:
|
|
|
|
Type Name Valid/Invalid
|
|
|
|
0 Invalid Invalid
|
|
1 Available 80286 TSS Valid
|
|
2 LDT Valid
|
|
3 Busy 80286 TSS Valid
|
|
4 80286 call gate Invalid
|
|
5 80286/80386 task gate Invalid
|
|
6 80286 trap gate Invalid
|
|
7 80286 interrupt gate Invalid
|
|
8 Invalid Valid
|
|
9 Available 80386 TSS Valid
|
|
A Invalid Invalid
|
|
B Busy 80386 TSS Valid
|
|
C 80386 call gate Invalid
|
|
D Invalid Invalid
|
|
E 80386 trap gate Invalid
|
|
F 80386 interrupt gate Invalid
|
|
|
|
Flags Affected
|
|
|
|
ZF as described above
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) for an illegal memory operand effective address in the CS, DS,
|
|
ES, FS, or GS segments; #SS(0) for an illegal address in the SS segment;
|
|
#PF(fault-code) for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 6; LSL is not recognized in Real Address Mode
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode
|
|
|
|
|
|
LTR ÄÄ Load Task Register
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
0F 00 /3 LTR r/m16 pm=23/27 Load EA word into task register
|
|
|
|
|
|
Description
|
|
|
|
LTR loads the task register from the source register or memory location
|
|
specified by the operand. The loaded task state segment is marked busy.
|
|
A task switch does not occur.
|
|
|
|
LTR is used only in operating system software; it is not used in
|
|
application programs.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) for an illegal memory operand effective address in the CS, DS,
|
|
ES, FS, or GS segments; #SS(0) for an illegal address in the SS segment;
|
|
#GP(0) if the current privilege level is not 0; #GP(selector) if the object
|
|
named by the source selector is not a TSS or is already busy;
|
|
#NP(selector) if the TSS is marked "not present"; #PF(fault-code) for
|
|
a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 6; LTR is not recognized in Real Address Mode
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode
|
|
|
|
Notes
|
|
|
|
The operand-size attribute has no effect on this instruction.
|
|
|
|
|
|
MOV ÄÄ Move Data
|
|
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
88 /r MOV r/m8,r8 2/2 Move byte register to r/m byte
|
|
89 /r MOV r/m16,r16 2/2 Move word register to r/m word
|
|
89 /r MOV r/m32,r32 2/2 Move dword register to r/m dword
|
|
8A /r MOV r8,r/m8 2/4 Move r/m byte to byte register
|
|
8B /r MOV r16,r/m16 2/4 Move r/m word to word register
|
|
8B /r MOV r32,r/m32 2/4 Move r/m dword to dword register
|
|
8C /r MOV r/m16,Sreg 2/2 Move segment register to r/m word
|
|
8D /r MOV Sreg,r/m16 2/5,pm=18/19 Move r/m word to segment register
|
|
A0 MOV AL,moffs8 4 Move byte at (seg:offset) to AL
|
|
A1 MOV AX,moffs16 4 Move word at (seg:offset) to AX
|
|
A1 MOV EAX,moffs32 4 Move dword at (seg:offset) to EAX
|
|
A2 MOV moffs8,AL 2 Move AL to (seg:offset)
|
|
A3 MOV moffs16,AX 2 Move AX to (seg:offset)
|
|
A3 MOV moffs32,EAX 2 Move EAX to (seg:offset)
|
|
B0 + rb MOV reg8,imm8 2 Move immediate byte to register
|
|
B8 + rw MOV reg16,imm16 2 Move immediate word to register
|
|
B8 + rd MOV reg32,imm32 2 Move immediate dword to register
|
|
C6 MOV r/m8,imm8 2/2 Move immediate byte to r/m byte
|
|
C7 MOV r/m16,imm16 2/2 Move immediate word to r/m word
|
|
C7 MOV r/m32,imm32 2/2 Move immediate dword to r/m dword
|
|
|
|
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
NOTES:
|
|
moffs8, moffs16, and moffs32 all consist of a simple offset relative
|
|
to the segment base. The 8, 16, and 32 refer to the size of the data. The
|
|
address-size attribute of the instruction determines the size of the
|
|
offset, either 16 or 32 bits.
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
|
|
Operation
|
|
|
|
DEST SRC;
|
|
|
|
Description
|
|
|
|
MOV copies the second operand to the first operand.
|
|
|
|
If the destination operand is a segment register (DS, ES, SS, etc.), then
|
|
data from a descriptor is also loaded into the register. The data for the
|
|
register is obtained from the descriptor table entry for the selector
|
|
given. A null selector (values 0000-0003) can be loaded into DS and ES
|
|
registers without causing an exception; however, use of DS or ES causes a
|
|
#GP(0), and no memory reference occurs.
|
|
|
|
A MOV into SS inhibits all interrupts until after the execution of the
|
|
next instruction (which is presumably a MOV into eSP).
|
|
|
|
Loading a segment register under 80386 Protected Mode results in special
|
|
checks and actions, as described in the following listing:
|
|
|
|
IF SS is loaded;
|
|
THEN
|
|
IF selector is null THEN #GP(0);
|
|
FI;
|
|
Selector index must be within its descriptor table limits else
|
|
#GP(selector);
|
|
Selector's RPL must equal CPL else #GP(selector);
|
|
AR byte must indicate a writable data segment else #GP(selector);
|
|
DPL in the AR byte must equal CPL else #GP(selector);
|
|
Segment must be marked present else #SS(selector);
|
|
Load SS with selector;
|
|
Load SS with descriptor.
|
|
FI;
|
|
IF DS, ES, FS or GS is loaded with non-null selector;
|
|
THEN
|
|
Selector index must be within its descriptor table limits
|
|
else #GP(selector);
|
|
AR byte must indicate data or readable code segment else
|
|
#GP(selector);
|
|
IF data or nonconforming code segment
|
|
THEN both the RPL and the CPL must be less than or equal to DPL in
|
|
AR byte;
|
|
ELSE #GP(selector);
|
|
FI;
|
|
Segment must be marked present else #NP(selector);
|
|
Load segment register with selector;
|
|
Load segment register with descriptor;
|
|
FI;
|
|
IF DS, ES, FS or GS is loaded with a null selector;
|
|
THEN
|
|
Load segment register with selector;
|
|
Clear descriptor valid bit;
|
|
FI;
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP, #SS, and #NP if a segment register is being loaded; otherwise,
|
|
#GP(0) if the destination is in a nonwritable segment; #GP(0) for an
|
|
illegal memory operand effective address in the CS, DS, ES, FS, or GS
|
|
segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code)
|
|
for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
|
|
fault
|
|
|
|
|
|
MOV ÄÄ Move to/from Special Registers
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
0F 20 /r MOV r32,CR0/CR2/CR3 6 Move (control register) to
|
|
(register)
|
|
0F 22 /r MOV CR0/CR2/CR3,r32 10/4/5 Move (register) to (control
|
|
register)
|
|
0F 21 /r MOV r32,DR0 -- 3 22 Move (debug register) to
|
|
(register)
|
|
0F 21 /r MOV r32,DR6/DR7 14 Move (debug register) to
|
|
(register)
|
|
0F 23 /r MOV DR0 -- 3,r32 22 Move (register) to (debug
|
|
register)
|
|
0F 23 /r MOV DR6/DR7,r32 16 Move (register) to (debug
|
|
register)
|
|
0F 24 /r MOV r32,TR6/TR7 12 Move (test register) to
|
|
(register)
|
|
0F 26 /r MOV TR6/TR7,r32 12 Move (register) to (test
|
|
register)
|
|
|
|
|
|
Operation
|
|
|
|
DEST SRC;
|
|
|
|
Description
|
|
|
|
The above forms of MOV store or load the following special registers in
|
|
or from a general purpose register:
|
|
|
|
þ Control registers CR0, CR2, and CR3
|
|
þ Debug Registers DR0, DR1, DR2, DR3, DR6, and DR7
|
|
þ Test Registers TR6 and TR7
|
|
|
|
32-bit operands are always used with these instructions, regardless of the
|
|
operand-size attribute.
|
|
|
|
Flags Affected
|
|
|
|
OF, SF, ZF, AF, PF, and CF are undefined
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the current privilege level is not 0
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
None
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
#GP(0) if instruction execution is attempted
|
|
|
|
Notes
|
|
|
|
The instructions must be executed at privilege level 0 or in real-address
|
|
mode; otherwise, a protection exception will be raised.
|
|
|
|
The reg field within the ModRM byte specifies which of the special
|
|
registers in each category is involved. The two bits in the field are
|
|
always 11. The r/m field specifies the general register involved.
|
|
|
|
|
|
MOVS/MOVSB/MOVSW/MOVSD ÄÄ Move Data from String to String
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
A4 MOVS m8,m8 7 Move byte [(E)SI] to ES:[(E)DI]
|
|
A5 MOVS m16,m16 7 Move word [(E)SI] to ES:[(E)DI]
|
|
A5 MOVS m32,m32 7 Move dword [(E)SI] to ES:[(E)DI]
|
|
A4 MOVSB 7 Move byte DS:[(E)SI] to ES:[(E)DI]
|
|
A5 MOVSW 7 Move word DS:[(E)SI] to ES:[(E)DI]
|
|
A5 MOVSD 7 Move dword DS:[(E)SI] to ES:[(E)DI]
|
|
|
|
|
|
Operation
|
|
|
|
IF (instruction = MOVSD) OR (instruction has doubleword operands)
|
|
THEN OperandSize 32;
|
|
ELSE OperandSize 16;
|
|
IF AddressSize = 16
|
|
THEN use SI for source-index and DI for destination-index;
|
|
ELSE (* AddressSize = 32 *)
|
|
use ESI for source-index and EDI for destination-index;
|
|
FI;
|
|
IF byte type of instruction
|
|
THEN
|
|
[destination-index] [source-index]; (* byte assignment *)
|
|
IF DF = 0 THEN IncDec 1 ELSE IncDec -1; FI;
|
|
ELSE
|
|
IF OperandSize = 16
|
|
THEN
|
|
[destination-index] [source-index]; (* word assignment *)
|
|
IF DF = 0 THEN IncDec 2 ELSE IncDec -2; FI;
|
|
ELSE (* OperandSize = 32 *)
|
|
[destination-index] [source-index]; (* doubleword assignment *)
|
|
IF DF = 0 THEN IncDec 4 ELSE IncDec -4; FI;
|
|
FI;
|
|
FI;
|
|
source-index source-index + IncDec;
|
|
destination-index destination-index + IncDec;
|
|
|
|
Description
|
|
|
|
MOVS copies the byte or word at [(E)SI] to the byte or word at
|
|
ES:[(E)DI]. The destination operand must be addressable from the ES
|
|
register; no segment override is possible for the destination. A segment
|
|
override can be used for the source operand; the default is DS.
|
|
|
|
The addresses of the source and destination are determined solely by the
|
|
contents of (E)SI and (E)DI. Load the correct index values into (E)SI
|
|
and (E)DI before executing the MOVS instruction. MOVSB, MOVSW,
|
|
and MOVSD are synonyms for the byte, word, and doubleword MOVS
|
|
instructions.
|
|
|
|
After the data is moved, both (E)SI and (E)DI are advanced
|
|
automatically. If the direction flag is 0 (CLD was executed), the registers
|
|
are incremented; if the direction flag is 1 (STD was executed), the
|
|
registers are decremented. The registers are incremented or decremented by 1
|
|
if a byte was moved, 2 if a word was moved, or 4 if a doubleword was moved.
|
|
|
|
MOVS can be preceded by the REP prefix for block movement of CX
|
|
bytes or words. Refer to the REP instruction for details of this operation.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
|
|
memory operand effective address in the CS, DS, ES, FS, or GS
|
|
segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code)
|
|
for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
|
|
fault
|
|
|
|
|
|
MOVSX ÄÄ Move with Sign-Extend
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
0F BE /r MOVSX r16,r/m8 3/6 Move byte to word with sign-extend
|
|
0F BE /r MOVSX r32,r/m8 3/6 Move byte to dword, sign-extend
|
|
0F BF /r MOVSX r32,r/m16 3/6 Move word to dword, sign-extend
|
|
|
|
|
|
Operation
|
|
|
|
DEST SignExtend(SRC);
|
|
|
|
Description
|
|
|
|
MOVSX reads the contents of the effective address or register as a byte
|
|
or a word, sign-extends the value to the operand-size attribute of the
|
|
instruction (16 or 32 bits), and stores the result in the destination
|
|
register.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) for an illegal memory operand effective address in the CS, DS,
|
|
ES, FS or GS segments; #SS(0) for an illegal address in the SS segment;
|
|
#PF(fault-code) for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
|
|
fault
|
|
|
|
|
|
MOVZX ÄÄ Move with Zero-Extend
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
0F B6 /r MOVZX r16,r/m8 3/6 Move byte to word with zero-extend
|
|
0F B6 /r MOVZX r32,r/m8 3/6 Move byte to dword, zero-extend
|
|
0F B7 /r MOVZX r32,r/m16 3/6 Move word to dword, zero-extend
|
|
|
|
|
|
Operation
|
|
|
|
DEST ZeroExtend(SRC);
|
|
|
|
Description
|
|
|
|
MOVZX reads the contents of the effective address or register as a byte
|
|
or a word, zero extends the value to the operand-size attribute of the
|
|
instruction (16 or 32 bits), and stores the result in the destination
|
|
register.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) for an illegal memory operand effective address in the CS, DS,
|
|
ES, FS, or GS segments; #SS(0) for an illegal address in the SS segment;
|
|
#PF(fault-code) for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
|
|
fault
|
|
|
|
|
|
MUL ÄÄ Unsigned Multiplication of AL or AX
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
F6 /4 MUL AL,r/m8 9-14/12-17 Unsigned multiply (AX AL * r/m byte)
|
|
F7 /4 MUL AX,r/m16 9-22/12-25 Unsigned multiply (DX:AX AX * r/m
|
|
word)
|
|
F7 /4 MUL EAX,r/m32 9-38/12-41 Unsigned multiply (EDX:EAX EAX * r/m
|
|
dword)
|
|
|
|
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
NOTES:
|
|
The 80386 uses an early-out multiply algorithm. The actual number of
|
|
clocks depends on the position of the most significant bit in the
|
|
optimizing multiplier, shown underlined above. The optimization occurs
|
|
for positive and negative multiplier values. Because of the early-out
|
|
algorithm, clock counts given are minimum to maximum. To calculate the
|
|
actual clocks, use the following formula:
|
|
|
|
Actual clock = if <> 0 then max(ceiling(log{2} ³m³), 3) + 6 clocks;
|
|
|
|
Actual clock = if = 0 then 9 clocks
|
|
|
|
where m is the multiplier.
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
|
|
Operation
|
|
|
|
IF byte-size operation
|
|
THEN AX AL * r/m8
|
|
ELSE (* word or doubleword operation *)
|
|
IF OperandSize = 16
|
|
THEN DX:AX AX * r/m16
|
|
ELSE (* OperandSize = 32 *)
|
|
EDX:EAX EAX * r/m32
|
|
FI;
|
|
FI;
|
|
|
|
Description
|
|
|
|
MUL performs unsigned multiplication. Its actions depend on the size
|
|
of its operand, as follows:
|
|
|
|
þ A byte operand is multiplied by AL; the result is left in AX. The
|
|
carry and overflow flags are set to 0 if AH is 0; otherwise, they are
|
|
set to 1.
|
|
|
|
þ A word operand is multiplied by AX; the result is left in DX:AX.
|
|
DX contains the high-order 16 bits of the product. The carry and
|
|
overflow flags are set to 0 if DX is 0; otherwise, they are set to 1.
|
|
|
|
þ A doubleword operand is multiplied by EAX and the result is left in
|
|
EDX:EAX. EDX contains the high-order 32 bits of the product. The
|
|
carry and overflow flags are set to 0 if EDX is 0; otherwise, they are
|
|
set to 1.
|
|
|
|
Flags Affected
|
|
|
|
OF and CF as described above; SF, ZF, AF, PF, and CF are undefined
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) for an illegal memory operand effective address in the CS, DS,
|
|
ES, FS, or GS segments; #SS(0) for an illegal address in the SS segment;
|
|
#PF(fault-code) for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
|
|
fault
|
|
|
|
|
|
NEG ÄÄ Two's Complement Negation
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
F6 /3 NEG r/m8 2/6 Two's complement negate r/m byte
|
|
F7 /3 NEG r/m16 2/6 Two's complement negate r/m word
|
|
F7 /3 NEG r/m32 2/6 Two's complement negate r/m dword
|
|
|
|
|
|
Operation
|
|
|
|
IF r/m = 0 THEN CF 0 ELSE CF 1; FI;
|
|
r/m - r/m;
|
|
|
|
Description
|
|
|
|
NEG replaces the value of a register or memory operand with its two's
|
|
complement. The operand is subtracted from zero, and the result is placed
|
|
in the operand.
|
|
|
|
The carry flag is set to 1, unless the operand is zero, in which case the
|
|
carry flag is cleared to 0.
|
|
|
|
Flags Affected
|
|
|
|
CF as described above; OF, SF, ZF, and PF as described in Appendix C
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
|
|
memory operand effective address in the CS, DS, ES, FS, or GS
|
|
segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code)
|
|
for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in real-address mode; #PF(fault-code) for a page
|
|
fault
|
|
|
|
|
|
NOP ÄÄ No Operation
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
90 NOP 3 No operation
|
|
|
|
|
|
Description
|
|
|
|
NOP performs no operation. NOP is a one-byte instruction that takes
|
|
up space but affects none of the machine context except (E)IP.
|
|
|
|
NOP is an alias mnemonic for the XCHG (E)AX, (E)AX instruction.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
None
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
None
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
None
|
|
|
|
|
|
NOT ÄÄ One's Complement Negation
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
F6 /2 NOT r/m8 2/6 Reverse each bit of r/m byte
|
|
F7 /2 NOT r/m16 2/6 Reverse each bit of r/m word
|
|
F7 /2 NOT r/m32 2/6 Reverse each bit of r/m dword
|
|
|
|
|
|
Operation
|
|
|
|
r/m NOT r/m;
|
|
|
|
Description
|
|
|
|
NOT inverts the operand; every 1 becomes a 0, and vice versa.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
|
|
memory operand effective address in the CS, DS, ES, FS, or GS
|
|
segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code)
|
|
for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in real-address mode; #PF(fault-code) for a page
|
|
fault
|
|
|
|
|
|
OR ÄÄ Logical Inclusive OR
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
0C ib OR AL,imm8 2 OR immediate byte to AL
|
|
0D iw OR AX,imm16 2 OR immediate word to AX
|
|
0D id OR EAX,imm32 2 OR immediate dword to EAX
|
|
80 /1 ib OR r/m8,imm8 2/7 OR immediate byte to r/m byte
|
|
81 /1 iw OR r/m16,imm16 2/7 OR immediate word to r/m word
|
|
81 /1 id OR r/m32,imm32 2/7 OR immediate dword to r/m dword
|
|
83 /1 ib OR r/m16,imm8 2/7 OR sign-extended immediate byte
|
|
with r/m word
|
|
83 /1 ib OR r/m32,imm8 2/7 OR sign-extended immediate byte
|
|
with r/m dword
|
|
08 /r OR r/m8,r8 2/6 OR byte register to r/m byte
|
|
09 /r OR r/m16,r16 2/6 OR word register to r/m word
|
|
09 /r OR r/m32,r32 2/6 OR dword register to r/m dword
|
|
0A /r OR r8,r/m8 2/7 OR byte register to r/m byte
|
|
0B /r OR r16,r/m16 2/7 OR word register to r/m word
|
|
0B /r OR r32,r/m32 2/7 OR dword register to r/m dword
|
|
|
|
|
|
Operation
|
|
|
|
DEST DEST OR SRC;
|
|
CF 0;
|
|
OF 0
|
|
|
|
Description
|
|
|
|
OR computes the inclusive OR of its two operands and places the result
|
|
in the first operand. Each bit of the result is 0 if both corresponding
|
|
bits of the operands are 0; otherwise, each bit is 1.
|
|
|
|
Flags Affected
|
|
|
|
OF 0, CF 0; SF, ZF, and PF as described in Appendix C; AF is
|
|
undefined
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
|
|
memory operand effective address in the CS, DS, ES, FS, or GS
|
|
segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code)
|
|
for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in real-address mode; #PF(fault-code) for a page
|
|
fault
|
|
|
|
|
|
OUT ÄÄ Output to Port
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
E6 ib OUT imm8,AL 10,pm=4*/24** Output byte AL to immediate port
|
|
number
|
|
E7 ib OUT imm8,AX 10,pm=4*/24** Output word AL to immediate port
|
|
number
|
|
E7 ib OUT imm8,EAX 10,pm=4*/24** Output dword AL to immediate
|
|
port number
|
|
EE OUT DX,AL 11,pm=5*/25** Output byte AL to port number in
|
|
DX
|
|
EF OUT DX,AX 11,pm=5*/25** Output word AL to port number in
|
|
DX
|
|
EF OUT DX,EAX 11,pm=5*/25** Output dword AL to port number
|
|
in DX
|
|
|
|
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
NOTES:
|
|
*If CPL ó IOPL
|
|
**If CPL > IOPL or if in virtual 8086 mode
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
|
|
Operation
|
|
|
|
IF (PE = 1) AND ((VM = 1) OR (CPL > IOPL))
|
|
THEN (* Virtual 8086 mode, or protected mode with CPL > IOPL *)
|
|
IF NOT I-O-Permission (DEST, width(DEST))
|
|
THEN #GP(0);
|
|
FI;
|
|
FI;
|
|
[DEST] SRC; (* I/O address space used *)
|
|
|
|
Description
|
|
|
|
OUT transfers a data byte or data word from the register (AL, AX, or
|
|
EAX) given as the second operand to the output port numbered by the
|
|
first operand. Output to any port from 0 to 65535 is performed by placing
|
|
the port number in the DX register and then using an OUT instruction
|
|
with DX as the first operand. If the instruction contains an eight-bit port
|
|
ID, that value is zero-extended to 16 bits.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the current privilege level is higher (has less privilege) than
|
|
IOPL and any of the corresponding I/O permission bits in TSS equals 1
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
None
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
#GP(0) fault if any of the corresponding I/O permission bits in TSS
|
|
equals 1
|
|
|
|
|
|
OUTS/OUTSB/OUTSW/OUTSD ÄÄ Output String to Port
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
6E OUTS DX,r/m8 14,pm=8*/28** Output byte [(E)SI] to port in DX
|
|
6F OUTS DX,r/m16 14,pm=8*/28** Output word [(E)SI] to port in DX
|
|
6F OUTS DX,r/m32 14,pm=8*/28** Output dword [(E)SI] to port in DX
|
|
6E OUTSB 14,pm=8*/28** Output byte DS:[(E)SI] to port in
|
|
DX
|
|
6F OUTSW 14,pm=8*/28** Output word DS:[(E)SI] to port in
|
|
DX
|
|
6F OUTSD 14,pm=8*/28** Output dword DS:[(E)SI] to port in
|
|
DX
|
|
|
|
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
NOTES:
|
|
*If CPL ó IOPL
|
|
**If CPL > IOPL or if in virtual 8086 mode
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
|
|
Operation
|
|
|
|
IF AddressSize = 16
|
|
THEN use SI for source-index;
|
|
ELSE (* AddressSize = 32 *)
|
|
use ESI for source-index;
|
|
FI;
|
|
|
|
IF (PE = 1) AND ((VM = 1) OR (CPL > IOPL))
|
|
THEN (* Virtual 8086 mode, or protected mode with CPL > IOPL *)
|
|
IF NOT I-O-Permission (DEST, width(DEST))
|
|
THEN #GP(0);
|
|
FI;
|
|
FI;
|
|
IF byte type of instruction
|
|
THEN
|
|
[DX] [source-index]; (* Write byte at DX I/O address *)
|
|
IF DF = 0 THEN IncDec 1 ELSE IncDec -1; FI;
|
|
FI;
|
|
IF OperandSize = 16
|
|
THEN
|
|
[DX] [source-index]; (* Write word at DX I/O address *)
|
|
IF DF = 0 THEN IncDec 2 ELSE IncDec -2; FI;
|
|
FI;
|
|
IF OperandSize = 32
|
|
THEN
|
|
[DX] [source-index]; (* Write dword at DX I/O address *)
|
|
IF DF = 0 THEN IncDec 4 ELSE IncDec -4; FI;
|
|
FI;
|
|
FI;
|
|
source-index source-index + IncDec;
|
|
|
|
Description
|
|
|
|
OUTS transfers data from the memory byte, word, or doubleword at the
|
|
source-index register to the output port addressed by the DX register. If
|
|
the address-size attribute for this instruction is 16 bits, SI is used for
|
|
the source-index register; otherwise, the address-size attribute is 32 bits,
|
|
and ESI is used for the source-index register.
|
|
|
|
OUTS does not allow specification of the port number as an immediate value.
|
|
The port must be addressed through the DX register value. Load the correct
|
|
value into DX before executing the OUTS instruction.
|
|
|
|
The address of the source data is determined by the contents of
|
|
source-index register. Load the correct index value into SI or ESI before
|
|
executing the OUTS instruction.
|
|
|
|
After the transfer, source-index register is advanced automatically. If
|
|
the direction flag is 0 (CLD was executed), the source-index register is
|
|
incremented; if the direction flag is 1 (STD was executed), it is
|
|
decremented. The amount of the increment or decrement is 1 if a byte is
|
|
output, 2 if a word is output, or 4 if a doubleword is output.
|
|
|
|
OUTSB, OUTSW, and OUTSD are synonyms for the byte, word, and
|
|
doubleword OUTS instructions. OUTS can be preceded by the REP
|
|
prefix for block output of CX bytes or words. Refer to the REP
|
|
instruction for details on this operation.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if CPL is greater than IOPL and any of the corresponding I/O
|
|
permission bits in TSS equals 1; #GP(0) for an illegal memory operand
|
|
effective address in the CS, DS, or ES segments; #SS(0) for an illegal
|
|
address in the SS segment; #PF(fault-code) for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
#GP(0) fault if any of the corresponding I/O permission bits in TSS
|
|
equals 1; #PF(fault-code) for a page fault
|
|
|
|
|
|
POP ÄÄ Pop a Word from the Stack
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
8F /0 POP m16 5 Pop top of stack into memory word
|
|
8F /0 POP m32 5 Pop top of stack into memory dword
|
|
58 + rw POP r16 4 Pop top of stack into word register
|
|
58 + rd POP r32 4 Pop top of stack into dword register
|
|
1F POP DS 7,pm=21 Pop top of stack into DS
|
|
07 POP ES 7,pm=21 Pop top of stack into ES
|
|
17 POP SS 7,pm=21 Pop top of stack into SS
|
|
0F A1 POP FS 7,pm=21 Pop top of stack into FS
|
|
0F A9 POP GS 7,pm=21 Pop top of stack into GS
|
|
|
|
|
|
Operation
|
|
|
|
IF StackAddrSize = 16
|
|
THEN
|
|
IF OperandSize = 16
|
|
THEN
|
|
DEST (SS:SP); (* copy a word *)
|
|
SP SP + 2;
|
|
ELSE (* OperandSize = 32 *)
|
|
DEST (SS:SP); (* copy a dword *)
|
|
SP SP + 4;
|
|
FI;
|
|
ELSE (* StackAddrSize = 32 * )
|
|
IF OperandSize = 16
|
|
THEN
|
|
DEST (SS:ESP); (* copy a word *)
|
|
ESP ESP + 2;
|
|
ELSE (* OperandSize = 32 *)
|
|
DEST (SS:ESP); (* copy a dword *)
|
|
ESP ESP + 4;
|
|
FI;
|
|
FI;
|
|
|
|
Description
|
|
|
|
POP replaces the previous contents of the memory, the register, or the
|
|
segment register operand with the word on the top of the 80386 stack,
|
|
addressed by SS:SP (address-size attribute of 16 bits) or SS:ESP
|
|
(addresssize attribute of 32 bits). The stack pointer SP is incremented
|
|
by 2 for an operand-size of 16 bits or by 4 for an operand-size of 32 bits.
|
|
It then points to the new top of stack.
|
|
|
|
POP CS is not an 80386 instruction. Popping from the stack into the CS
|
|
register is accomplished with a RET instruction.
|
|
|
|
If the destination operand is a segment register (DS, ES, FS, GS, or
|
|
SS), the value popped must be a selector. In protected mode, loading the
|
|
selector initiates automatic loading of the descriptor information
|
|
associated with that selector into the hidden part of the segment register;
|
|
loading also initiates validation of both the selector and the descriptor
|
|
information.
|
|
|
|
A null value (0000-0003) may be popped into the DS, ES, FS, or GS
|
|
register without causing a protection exception. An attempt to reference
|
|
a segment whose corresponding segment register is loaded with a null
|
|
value causes a #GP(0) exception. No memory reference occurs. The saved
|
|
value of the segment register is null.
|
|
|
|
A POP SS instruction inhibits all interrupts, including NMI, until after
|
|
execution of the next instruction. This allows sequential execution of POP
|
|
SS and POP eSP instructions without danger of having an invalid stack
|
|
during an interrupt. However, use of the LSS instruction is the preferred
|
|
method of loading the SS and eSP registers.
|
|
|
|
Loading a segment register while in protected mode results in special
|
|
checks and actions, as described in the following listing:
|
|
|
|
IF SS is loaded:
|
|
IF selector is null THEN #GP(0);
|
|
Selector index must be within its descriptor table limits ELSE
|
|
#GP(selector);
|
|
Selector's RPL must equal CPL ELSE #GP(selector);
|
|
AR byte must indicate a writable data segment ELSE #GP(selector);
|
|
DPL in the AR byte must equal CPL ELSE #GP(selector);
|
|
Segment must be marked present ELSE #SS(selector);
|
|
Load SS register with selector;
|
|
Load SS register with descriptor;
|
|
|
|
IF DS, ES, FS or GS is loaded with non-null selector:
|
|
AR byte must indicate data or readable code segment ELSE
|
|
#GP(selector);
|
|
IF data or nonconforming code
|
|
THEN both the RPL and the CPL must be less than or equal to DPL in
|
|
AR byte
|
|
ELSE #GP(selector);
|
|
FI;
|
|
Segment must be marked present ELSE #NP(selector);
|
|
Load segment register with selector;
|
|
Load segment register with descriptor;
|
|
|
|
IF DS, ES, FS, or GS is loaded with a null selector:
|
|
Load segment register with selector
|
|
Clear valid bit in invisible portion of register
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP, #SS, and #NP if a segment register is being loaded; #SS(0) if the
|
|
current top of stack is not within the stack segment; #GP(0) if the result
|
|
is in a nonwritable segment; #GP(0) for an illegal memory operand
|
|
effective address in the CS, DS, ES, FS, or GS segments; #SS(0) for an
|
|
illegal address in the SS segment; #PF(fault-code) for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in real-address mode; #PF(fault-code) for a page
|
|
fault
|
|
|
|
|
|
POPA/POPAD ÄÄ Pop all General Registers
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
61 POPA 24 Pop DI, SI, BP, SP, BX, DX, CX, and AX
|
|
61 POPAD 24 Pop EDI, ESI, EBP, ESP, EDX, ECX, and EAX
|
|
|
|
|
|
Operation
|
|
|
|
IF OperandSize = 16 (* instruction = POPA *)
|
|
THEN
|
|
DI Pop();
|
|
SI Pop();
|
|
BP Pop();
|
|
throwaway Pop (); (* Skip SP *)
|
|
BX Pop();
|
|
DX Pop();
|
|
CX Pop();
|
|
AX Pop();
|
|
ELSE (* OperandSize = 32, instruction = POPAD *)
|
|
EDI Pop();
|
|
ESI Pop();
|
|
EBP Pop();
|
|
throwaway Pop (); (* Skip ESP *)
|
|
EBX Pop();
|
|
EDX Pop();
|
|
ECX Pop();
|
|
EAX Pop();
|
|
FI;
|
|
|
|
Description
|
|
|
|
POPA pops the eight 16-bit general registers. However, the SP value is
|
|
discarded instead of loaded into SP. POPA reverses a previous PUSHA,
|
|
restoring the general registers to their values before PUSHA was
|
|
executed. The first register popped is DI.
|
|
|
|
POPAD pops the eight 32-bit general registers. The ESP value is
|
|
discarded instead of loaded into ESP. POPAD reverses the previous
|
|
PUSHAD, restoring the general registers to their values before PUSHAD
|
|
was executed. The first register popped is EDI.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#SS(0) if the starting or ending stack address is not within the stack
|
|
segment; #PF(fault-code) for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in real-address mode; #PF(fault-code) for a page
|
|
fault
|
|
|
|
|
|
POPF/POPFD ÄÄ Pop Stack into FLAGS or EFLAGS Register
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
9D POPF 5 Pop top of stack FLAGS
|
|
9D POPFD 5 Pop top of stack into EFLAGS
|
|
|
|
|
|
Operation
|
|
|
|
Flags Pop();
|
|
|
|
Description
|
|
|
|
POPF/POPFD pops the word or doubleword on the top of the stack and
|
|
stores the value in the flags register. If the operand-size attribute of
|
|
the instruction is 16 bits, then a word is popped and the value is stored in
|
|
FLAGS. If the operand-size attribute is 32 bits, then a doubleword is popped
|
|
and the value is stored in EFLAGS.
|
|
|
|
Refer to Chapter 2 and Chapter 4 for information about the FLAGS
|
|
and EFLAGS registers. Note that bits 16 and 17 of EFLAGS, called
|
|
VM and RF, respectively, are not affected by POPF or POPFD.
|
|
|
|
The I/O privilege level is altered only when executing at privilege level
|
|
0. The interrupt flag is altered only when executing at a level at least as
|
|
privileged as the I/O privilege level. (Real-address mode is equivalent to
|
|
privilege level 0.) If a POPF instruction is executed with insufficient
|
|
privilege, an exception does not occur, but the privileged bits do not
|
|
change.
|
|
|
|
Flags Affected
|
|
|
|
All flags except VM and RF
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#SS(0) if the top of stack is not within the stack segment
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
#GP(0) fault if IOPL is less than 3, to permit emulation
|
|
|
|
|
|
PUSH ÄÄ Push Operand onto the Stack
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
FF /6 PUSH m16 5 Push memory word
|
|
FF /6 PUSH m32 5 Push memory dword
|
|
50 + /r PUSH r16 2 Push register word
|
|
50 + /r PUSH r32 2 Push register dword
|
|
6A PUSH imm8 2 Push immediate byte
|
|
68 PUSH imm16 2 Push immediate word
|
|
68 PUSH imm32 2 Push immediate dword
|
|
0E PUSH CS 2 Push CS
|
|
16 PUSH SS 2 Push SS
|
|
1E PUSH DS 2 Push DS
|
|
06 PUSH ES 2 Push ES
|
|
0F A0 PUSH FS 2 Push FS
|
|
OF A8 PUSH GS 2 Push GS
|
|
|
|
|
|
Operation
|
|
|
|
IF StackAddrSize = 16
|
|
THEN
|
|
IF OperandSize = 16 THEN
|
|
SP SP - 2;
|
|
(SS:SP) (SOURCE); (* word assignment *)
|
|
ELSE
|
|
SP SP - 4;
|
|
(SS:SP) (SOURCE); (* dword assignment *)
|
|
FI;
|
|
ELSE (* StackAddrSize = 32 *)
|
|
IF OperandSize = 16
|
|
THEN
|
|
ESP ESP - 2;
|
|
(SS:ESP) (SOURCE); (* word assignment *)
|
|
ELSE
|
|
ESP ESP - 4;
|
|
(SS:ESP) (SOURCE); (* dword assignment *)
|
|
FI;
|
|
FI;
|
|
|
|
Description
|
|
|
|
PUSH decrements the stack pointer by 2 if the operand-size attribute of
|
|
the instruction is 16 bits; otherwise, it decrements the stack pointer by
|
|
4. PUSH then places the operand on the new top of stack, which is
|
|
pointed to by the stack pointer.
|
|
|
|
The 80386 PUSH eSP instruction pushes the value of eSP as it existed
|
|
before the instruction. This differs from the 8086, where PUSH SP
|
|
pushes the new value (decremented by 2).
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#SS(0) if the new value of SP or ESP is outside the stack segment limit;
|
|
#GP(0) for an illegal memory operand effective address in the CS, DS,
|
|
ES, FS, or GS segments; #SS(0) for an illegal address in the SS segment;
|
|
#PF(fault-code) for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
None; if SP or ESP is 1, the 80386 shuts down due to a lack of stack
|
|
space
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in real-address mode; #PF(fault-code) for a page
|
|
fault
|
|
|
|
|
|
PUSHA/PUSHAD ÄÄ Push all General Registers
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
60 PUSHA 18 Push AX, CX, DX, BX, original SP, BP, SI, and
|
|
DI
|
|
60 PUSHAD 18 Push EAX, ECX, EDX, EBX, original ESP, EBP,
|
|
ESI, and EDI
|
|
|
|
|
|
Operation
|
|
|
|
IF OperandSize = 16 (* PUSHA instruction *)
|
|
THEN
|
|
Temp (SP);
|
|
Push(AX);
|
|
Push(CX);
|
|
Push(DX);
|
|
Push(BX);
|
|
Push(Temp);
|
|
Push(BP);
|
|
Push(SI);
|
|
Push(DI);
|
|
ELSE (* OperandSize = 32, PUSHAD instruction *)
|
|
Temp (ESP);
|
|
Push(EAX);
|
|
Push(ECX);
|
|
Push(EDX);
|
|
Push(EBX);
|
|
Push(Temp);
|
|
Push(EBP);
|
|
Push(ESI);
|
|
Push(EDI);
|
|
FI;
|
|
|
|
Description
|
|
|
|
PUSHA and PUSHAD save the 16-bit or 32-bit general registers,
|
|
respectively, on the 80386 stack. PUSHA decrements the stack pointer
|
|
(SP) by 16 to hold the eight word values. PUSHAD decrements the
|
|
stack pointer (ESP) by 32 to hold the eight doubleword values. Because
|
|
the registers are pushed onto the stack in the order in which they were
|
|
given, they appear in the 16 or 32 new stack bytes in reverse order. The
|
|
last register pushed is DI or EDI.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#SS(0) if the starting or ending stack address is outside the stack segment
|
|
limit; #PF(fault-code) for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Before executing PUSHA or PUSHAD, the 80386 shuts down if SP or
|
|
ESP equals 1, 3, or 5; if SP or ESP equals 7, 9, 11, 13, or 15, exception
|
|
13 occurs
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in real-address mode; #PF(fault-code) for a page
|
|
fault
|
|
|
|
|
|
PUSHF/PUSHFD ÄÄ Push Flags Register onto the Stack
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
9C PUSHF 4 Push FLAGS
|
|
9C PUSHFD 4 Push EFLAGS
|
|
|
|
|
|
Operation
|
|
|
|
IF OperandSize = 32
|
|
THEN push(EFLAGS);
|
|
ELSE push(FLAGS);
|
|
FI;
|
|
|
|
Description
|
|
|
|
PUSHF decrements the stack pointer by 2 and copies the FLAGS
|
|
register to the new top of stack; PUSHFD decrements the stack pointer by
|
|
4, and the 80386 EFLAGS register is copied to the new top of stack
|
|
which is pointed to by SS:eSP. Refer to Chapter 2 and Chapter 4 for
|
|
information on the EFLAGS register.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#SS(0) if the new value of eSP is outside the stack segment boundaries
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
None; the 80386 shuts down due to a lack of stack space
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
#GP(0) fault if IOPL is less than 3, to permit emulation
|
|
|
|
|
|
RCL/RCR/ROL/ROR ÄÄ Rotate
|
|
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
D0 /2 RCL r/m8,1 9/10 Rotate 9 bits (CF,r/m byte) left
|
|
once
|
|
D2 /2 RCL r/m8,CL 9/10 Rotate 9 bits (CF,r/m byte) left CL
|
|
times
|
|
C0 /2 ib RCL r/m8,imm8 9/10 Rotate 9 bits (CF,r/m byte) left
|
|
imm8 times
|
|
D1 /2 RCL r/m16,1 9/10 Rotate 17 bits (CF,r/m word) left
|
|
once
|
|
D3 /2 RCL r/m16,CL 9/10 Rotate 17 bits (CF,r/m word) left
|
|
CL times
|
|
C1 /2 ib RCL r/m16,imm8 9/10 Rotate 17 bits (CF,r/m word) left
|
|
imm8 times
|
|
D1 /2 RCL r/m32,1 9/10 Rotate 33 bits (CF,r/m dword) left
|
|
once
|
|
D3 /2 RCL r/m32,CL 9/10 Rotate 33 bits (CF,r/m dword) left
|
|
CL times
|
|
C1 /2 ib RCL r/m32,imm8 9/10 Rotate 33 bits (CF,r/m dword) left
|
|
imm8 times
|
|
D0 /3 RCR r/m8,1 9/10 Rotate 9 bits (CF,r/m byte) right
|
|
once
|
|
D2 /3 RCR r/m8,CL 9/10 Rotate 9 bits (CF,r/m byte) right
|
|
CL times
|
|
C0 /3 ib RCR r/m8,imm8 9/10 Rotate 9 bits (CF,r/m byte) right
|
|
imm8 times
|
|
D1 /3 RCR r/m16,1 9/10 Rotate 17 bits (CF,r/m word) right
|
|
once
|
|
D3 /3 RCR r/m16,CL 9/10 Rotate 17 bits (CF,r/m word) right
|
|
CL times
|
|
C1 /3 ib RCR r/m16,imm8 9/10 Rotate 17 bits (CF,r/m word) right
|
|
imm8 times
|
|
D1 /3 RCR r/m32,1 9/10 Rotate 33 bits (CF,r/m dword) right
|
|
once
|
|
D3 /3 RCR r/m32,CL 9/10 Rotate 33 bits (CF,r/m dword) right
|
|
CL times
|
|
C1 /3 ib RCR r/m32,imm8 9/10 Rotate 33 bits (CF,r/m dword) right
|
|
imm8 times
|
|
D0 /0 ROL r/m8,1 3/7 Rotate 8 bits r/m byte left once
|
|
D2 /0 ROL r/m8,CL 3/7 Rotate 8 bits r/m byte left CL
|
|
times
|
|
C0 /0 ib ROL r/m8,imm8 3/7 Rotate 8 bits r/m byte left imm8
|
|
times
|
|
D1 /0 ROL r/m16,1 3/7 Rotate 16 bits r/m word left once
|
|
D3 /0 ROL r/m16,CL 3/7 Rotate 16 bits r/m word left CL
|
|
times
|
|
C1 /0 ib ROL r/m16,imm8 3/7 Rotate 16 bits r/m word left imm8
|
|
times
|
|
D1 /0 ROL r/m32,1 3/7 Rotate 32 bits r/m dword left once
|
|
D3 /0 ROL r/m32,CL 3/7 Rotate 32 bits r/m dword left CL
|
|
times
|
|
C1 /0 ib ROL r/m32,imm8 3/7 Rotate 32 bits r/m dword left imm8
|
|
times
|
|
D0 /1 ROR r/m8,1 3/7 Rotate 8 bits r/m byte right once
|
|
D2 /1 ROR r/m8,CL 3/7 Rotate 8 bits r/m byte right CL
|
|
times
|
|
C0 /1 ib ROR r/m8,imm8 3/7 Rotate 8 bits r/m word right imm8
|
|
times
|
|
D1 /1 ROR r/m16,1 3/7 Rotate 16 bits r/m word right once
|
|
D3 /1 ROR r/m16,CL 3/7 Rotate 16 bits r/m word right CL
|
|
times
|
|
C1 /1 ib ROR r/m16,imm8 3/7 Rotate 16 bits r/m word right imm8
|
|
times
|
|
D1 /1 ROR r/m32,1 3/7 Rotate 32 bits r/m dword right once
|
|
D3 /1 ROR r/m32,CL 3/7 Rotate 32 bits r/m dword right CL
|
|
times
|
|
C1 /1 ib ROR r/m32,imm8 3/7 Rotate 32 bits r/m dword right imm8
|
|
times
|
|
|
|
|
|
Operation
|
|
|
|
(* ROL - Rotate Left *)
|
|
temp COUNT;
|
|
WHILE (temp <> 0)
|
|
DO
|
|
tmpcf high-order bit of (r/m);
|
|
r/m r/m * 2 + (tmpcf);
|
|
temp temp - 1;
|
|
OD;
|
|
IF COUNT = 1
|
|
THEN
|
|
IF high-order bit of r/m <> CF
|
|
THEN OF 1;
|
|
ELSE OF 0;
|
|
FI;
|
|
ELSE OF undefined;
|
|
FI;
|
|
(* ROR - Rotate Right *)
|
|
temp COUNT;
|
|
WHILE (temp <> 0 )
|
|
DO
|
|
tmpcf low-order bit of (r/m);
|
|
r/m r/m / 2 + (tmpcf * 2^(width(r/m)));
|
|
temp temp - 1;
|
|
DO;
|
|
IF COUNT = 1
|
|
THEN
|
|
IF (high-order bit of r/m) <> (bit next to high-order bit of r/m)
|
|
THEN OF 1;
|
|
ELSE OF 0;
|
|
FI;
|
|
ELSE OF undefined;
|
|
FI;
|
|
|
|
Description
|
|
|
|
Each rotate instruction shifts the bits of the register or memory operand
|
|
given. The left rotate instructions shift all the bits upward, except for
|
|
the top bit, which is returned to the bottom. The right rotate instructions
|
|
do the reverse: the bits shift downward until the bottom bit arrives at
|
|
the top.
|
|
|
|
For the RCL and RCR instructions, the carry flag is part of the rotated
|
|
quantity. RCL shifts the carry flag into the bottom bit and shifts the top
|
|
bit into the carry flag; RCR shifts the carry flag into the top bit and
|
|
shifts the bottom bit into the carry flag. For the ROL and ROR
|
|
instructions, the original value of the carry flag is not a part of the
|
|
result, but the carry flag receives a copy of the bit that was shifted from
|
|
one end to the other.
|
|
|
|
The rotate is repeated the number of times indicated by the second
|
|
operand, which is either an immediate number or the contents of the CL
|
|
register. To reduce the maximum instruction execution time, the 80386
|
|
does not allow rotation counts greater than 31. If a rotation count greater
|
|
than 31 is attempted, only the bottom five bits of the rotation are used.
|
|
The 8086 does not mask rotation counts. The 80386 in Virtual 8086 Mode does
|
|
mask rotation counts.
|
|
|
|
The overflow flag is defined only for the single-rotate forms of the
|
|
instructions (second operand = 1). It is undefined in all other cases. For
|
|
left shifts/rotates, the CF bit after the shift is XORed with the
|
|
high-order result bit. For right shifts/rotates, the high-order two bits of
|
|
the result are XORed to get OF.
|
|
|
|
Flags Affected
|
|
|
|
OF only for single rotates; OF is undefined for multi-bit rotates; CF as
|
|
described above
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
|
|
memory operand effective address in the CS, DS, ES, FS, or GS
|
|
segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code)
|
|
for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
|
|
fault
|
|
|
|
|
|
REP/REPE/REPZ/REPNE/REPNZ ÄÄ Repeat Following String Operation
|
|
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
F3 6C REP INS r/m8, DX 13+6*(E)CX,
|
|
pm=7+6*(E)CX
|
|
If CPL ó IOPL/
|
|
27+6*(E)CX
|
|
If CPL > IOPL or if in virtual 8086 mode Input (E)CX bytes from port
|
|
DX into ES:[(E)DI]
|
|
F3 6D REP INS r/m16,DX 13+6*(E)CX,
|
|
pm=7+6*(E)CX
|
|
If CPL ó IOPL/
|
|
27+6*(E)CX
|
|
If CPL > IOPL or if in virtual 8086 mode Input (E)CX words from port
|
|
DX into ES:[(E)DI]
|
|
F3 6D REP INS r/m32,DX 13+6*(E)CX,
|
|
pm=7+6*(E)CX
|
|
If CPL ó IOPL/
|
|
27+6*(E)CX
|
|
If CPL > IOPL or if in virtual 8086 mode Input (E)CX dwords from port
|
|
DX into ES:[(E)DI]
|
|
F3 A4 REP MOVS m8,m8 5+4*(E)CX Move (E)CX bytes from
|
|
[(E)SI] to ES:[(E)DI]
|
|
F3 A5 REP MOVS m16,m16 5+4*(E)CX Move (E)CX words from
|
|
[(E)SI] to ES:[(E)DI]
|
|
F3 A5 REP MOVS m32,m32 5+4*(E)CX Move (E)CX dwords from
|
|
[(E)SI] to ES:[(E)DI]
|
|
F3 6E REP OUTS DX,r/m8 5+12*(E)CX,
|
|
pm=6+5*(E)CX
|
|
If CPL ó IOPL/
|
|
26+5*(E)CX
|
|
If CPL > IOPL or if in virtual 8086 mode Output (E)CX bytes from
|
|
[(E)SI] to port DX
|
|
F3 6F REP OUTS DX,r/m16 5+12*(E)CX,
|
|
pm=6+5*(E)CX
|
|
If CPL ó IOPL/
|
|
26+5*(E)CX
|
|
If CPL > IOPL or if in virtual 8086 mode Output (E)CX words from
|
|
[(E)SI] to port DX
|
|
F3 6F REP OUTS DX,r/m32 5+12*(E)CX,
|
|
pm=6+5*(E)CX
|
|
If CPL ó IOPL/
|
|
26+5*(E)CX
|
|
If CPL > IOPL or if in virtual 8086 mode Output (E)CX dwords from
|
|
[(E)SI] to port DX
|
|
F3 AA REP STOS m8 5+5*(E)CX Fill (E)CX bytes at
|
|
ES:[(E)DI] with AL
|
|
F3 AB REP STOS m16 5+5*(E)CX Fill (E)CX words at
|
|
ES:[(E)DI] with AX
|
|
F3 AB REP STOS m32 5+5*(E)CX Fill (E)CX dwords at
|
|
ES:[(E)DI] with EAX
|
|
F3 A6 REPE CMPS m8,m8 5+9*N Find nonmatching bytes in
|
|
ES:[(E)DI] and [(E)SI]
|
|
F3 A7 REPE CMPS m16,m16 5+9*N Find nonmatching words in
|
|
ES:[(E)DI] and [(E)SI]
|
|
F3 A7 REPE CMPS m32,m32 5+9*N Find nonmatching dwords in
|
|
ES:[(E)DI] and [(E)SI]
|
|
F3 AE REPE SCAS m8 5+8*N Find non-AL byte starting
|
|
at ES:[(E)DI]
|
|
F3 AF REPE SCAS m16 5+8*N Find non-AX word starting
|
|
at ES:[(E)DI]
|
|
F3 AF REPE SCAS m32 5+8*N Find non-EAX dword starting
|
|
at ES:[(E)DI]
|
|
F2 A6 REPNE CMPS m8,m8 5+9*N Find matching bytes in
|
|
ES:[(E)DI] and [(E)SI]
|
|
F2 A7 REPNE CMPS m16,m16 5+9*N Find matching words in
|
|
ES:[(E)DI] and [(E)SI]
|
|
F2 A7 REPNE CMPS m32,m32 5+9*N Find matching dwords in
|
|
ES:[(E)DI] and [(E)SI]
|
|
F2 AE REPNE SCAS m8 5+8*N Find AL, starting at
|
|
ES:[(E)DI]
|
|
F2 AF REPNE SCAS m16 5+8*N Find AX, starting at
|
|
ES:[(E)DI]
|
|
F2 AF REPNE SCAS m32 5+8*N Find EAX, starting at
|
|
ES:[(E)DI]
|
|
|
|
|
|
Operation
|
|
|
|
IF AddressSize = 16
|
|
THEN use CX for CountReg;
|
|
ELSE (* AddressSize = 32 *) use ECX for CountReg;
|
|
FI;
|
|
WHILE CountReg <> 0
|
|
DO
|
|
service pending interrupts (if any);
|
|
perform primitive string instruction;
|
|
CountReg CountReg - 1;
|
|
IF primitive operation is CMPB, CMPW, SCAB, or SCAW
|
|
THEN
|
|
IF (instruction is REP/REPE/REPZ) AND (ZF=1)
|
|
THEN exit WHILE loop
|
|
ELSE
|
|
IF (instruction is REPNZ or REPNE) AND (ZF=0)
|
|
THEN exit WHILE loop;
|
|
FI;
|
|
FI;
|
|
FI;
|
|
OD;
|
|
|
|
Description
|
|
|
|
REP, REPE (repeat while equal), and REPNE (repeat while not equal)
|
|
are prefix that are applied to string operation. Each prefix cause the
|
|
string instruction that follows to be repeated the number of times
|
|
indicated in the count register or (for REPE and REPNE) until the
|
|
indicated condition in the zero flag is no longer met.
|
|
|
|
Synonymous forms of REPE and REPNE are REPZ and REPNZ,
|
|
respectively.
|
|
|
|
The REP prefixes apply only to one string instruction at a time. To repeat
|
|
a block of instructions, use the LOOP instruction or another looping
|
|
construct.
|
|
|
|
The precise action for each iteration is as follows:
|
|
|
|
1. If the address-size attribute is 16 bits, use CX for the count
|
|
register; if the address-size attribute is 32 bits, use ECX for the
|
|
count register.
|
|
|
|
2. Check CX. If it is zero, exit the iteration, and move to the next
|
|
instruction.
|
|
|
|
3. Acknowledge any pending interrupts.
|
|
|
|
4. Perform the string operation once.
|
|
|
|
5. Decrement CX or ECX by one; no flags are modified.
|
|
|
|
6. Check the zero flag if the string operation is SCAS or CMPS. If
|
|
the repeat condition does not hold, exit the iteration and move to
|
|
the next instruction. Exit the iteration if the prefix is REPE and ZF
|
|
is 0 (the last comparison was not equal), or if the prefix is REPNE
|
|
and ZF is one (the last comparison was equal).
|
|
|
|
7. Return to step 1 for the next iteration.
|
|
|
|
Repeated CMPS and SCAS instructions can be exited if the count is
|
|
exhausted or if the zero flag fails the repeat condition. These two cases
|
|
can be distinguished by using either the JCXZ instruction, or by using
|
|
the conditional jumps that test the zero flag (JZ, JNZ, and JNE).
|
|
|
|
Flags Affected
|
|
|
|
ZF by REP CMPS and REP SCAS as described above
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#UD if a repeat prefix is used before an instruction that is not in the
|
|
list above; further exceptions can be generated when the string operation is
|
|
executed; refer to the descriptions of the string instructions themselves
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 6 if a repeat prefix is used before an instruction that is not in
|
|
the list above; further exceptions can be generated when the string
|
|
operation is executed; refer to the descriptions of the string instructions
|
|
themselves
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
#UD if a repeat prefix is used before an instruction that is not in the
|
|
list above; further exceptions can be generated when the string operation is
|
|
executed; refer to the descriptions of the string instructions themselves
|
|
|
|
Notes
|
|
|
|
Not all input/output ports can handle the rate at which the REP INS
|
|
and REP OUTS instructions execute.
|
|
|
|
|
|
RET ÄÄ Return from Procedure
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
C3 RET 10+m Return (near) to caller
|
|
CB RET 18+m,pm=32+m Return (far) to caller, same
|
|
privilege
|
|
CB RET pm=68 Return (far), lesser privilege,
|
|
switch stacks
|
|
C2 iw RET imm16 10+m Return (near), pop imm16 bytes of
|
|
parameters
|
|
CA iw RET imm16 18+m,pm=32+m Return (far), same privilege, pop
|
|
imm16 bytes
|
|
CA iw RET imm16 pm=68 Return (far), lesser privilege, pop
|
|
imm16 bytes
|
|
|
|
|
|
Operation
|
|
|
|
IF instruction = near RET
|
|
THEN;
|
|
IF OperandSize = 16
|
|
THEN
|
|
IP Pop();
|
|
EIP EIP AND 0000FFFFH;
|
|
ELSE (* OperandSize = 32 *)
|
|
EIP Pop();
|
|
FI;
|
|
IF instruction has immediate operand THEN eSP eSP + imm16; FI;
|
|
FI;
|
|
|
|
IF (PE = 0 OR (PE = 1 AND VM = 1))
|
|
(* real mode or virtual 8086 mode *)
|
|
AND instruction = far RET
|
|
THEN;
|
|
IF OperandSize = 16
|
|
THEN
|
|
IP Pop();
|
|
EIP EIP AND 0000FFFFH;
|
|
CS Pop(); (* 16-bit pop *)
|
|
ELSE (* OperandSize = 32 *)
|
|
EIP Pop();
|
|
CS Pop(); (* 32-bit pop, high-order 16-bits discarded *)
|
|
FI;
|
|
IF instruction has immediate operand THEN eSP eSP + imm16; FI;
|
|
FI;
|
|
|
|
IF (PE = 1 AND VM = 0) (* Protected mode, not V86 mode *)
|
|
AND instruction = far RET
|
|
THEN
|
|
IF OperandSize=32
|
|
THEN Third word on stack must be within stack limits else #SS(0);
|
|
ELSE Second word on stack must be within stack limits else #SS(0);
|
|
FI;
|
|
Return selector RPL must be ò CPL ELSE #GP(return selector)
|
|
IF return selector RPL = CPL
|
|
THEN GOTO SAME-LEVEL;
|
|
ELSE GOTO OUTER-PRIVILEGE-LEVEL;
|
|
FI;
|
|
FI;
|
|
|
|
SAME-LEVEL:
|
|
Return selector must be non-null ELSE #GP(0)
|
|
Selector index must be within its descriptor table limits ELSE
|
|
#GP(selector)
|
|
Descriptor AR byte must indicate code segment ELSE #GP(selector)
|
|
IF non-conforming
|
|
THEN code segment DPL must equal CPL;
|
|
ELSE #GP(selector);
|
|
FI;
|
|
IF conforming
|
|
THEN code segment DPL must be ó CPL;
|
|
ELSE #GP(selector);
|
|
FI;
|
|
Code segment must be present ELSE #NP(selector);
|
|
Top word on stack must be within stack limits ELSE #SS(0);
|
|
IP must be in code segment limit ELSE #GP(0);
|
|
IF OperandSize=32
|
|
THEN
|
|
Load CS:EIP from stack
|
|
Load CS register with descriptor
|
|
Increment eSP by 8 plus the immediate offset if it exists
|
|
ELSE (* OperandSize=16 *)
|
|
Load CS:IP from stack
|
|
Load CS register with descriptor
|
|
Increment eSP by 4 plus the immediate offset if it exists
|
|
FI;
|
|
|
|
OUTER-PRIVILEGE-LEVEL:
|
|
IF OperandSize=32
|
|
THEN Top (16+immediate) bytes on stack must be within stack limits
|
|
ELSE #SS(0);
|
|
ELSE Top (8+immediate) bytes on stack must be within stack limits ELSE
|
|
#SS(0);
|
|
FI;
|
|
Examine return CS selector and associated descriptor:
|
|
Selector must be non-null ELSE #GP(0);
|
|
Selector index must be within its descriptor table limits ELSE
|
|
#GP(selector)
|
|
Descriptor AR byte must indicate code segment ELSE #GP(selector);
|
|
IF non-conforming
|
|
THEN code segment DPL must equal return selector RPL
|
|
ELSE #GP(selector);
|
|
FI;
|
|
IF conforming
|
|
THEN code segment DPL must be ó return selector RPL;
|
|
ELSE #GP(selector);
|
|
FI;
|
|
Segment must be present ELSE #NP(selector)
|
|
Examine return SS selector and associated descriptor:
|
|
Selector must be non-null ELSE #GP(0);
|
|
Selector index must be within its descriptor table limits
|
|
ELSE #GP(selector);
|
|
Selector RPL must equal the RPL of the return CS selector ELSE
|
|
#GP(selector);
|
|
Descriptor AR byte must indicate a writable data segment ELSE
|
|
#GP(selector);
|
|
Descriptor DPL must equal the RPL of the return CS selector ELSE
|
|
#GP(selector);
|
|
Segment must be present ELSE #NP(selector);
|
|
IP must be in code segment limit ELSE #GP(0);
|
|
Set CPL to the RPL of the return CS selector;
|
|
IF OperandMode=32
|
|
THEN
|
|
Load CS:EIP from stack;
|
|
Set CS RPL to CPL;
|
|
Increment eSP by 8 plus the immediate offset if it exists;
|
|
Load SS:eSP from stack;
|
|
ELSE (* OperandMode=16 *)
|
|
Load CS:IP from stack;
|
|
Set CS RPL to CPL;
|
|
Increment eSP by 4 plus the immediate offset if it exists;
|
|
Load SS:eSP from stack;
|
|
FI;
|
|
Load the CS register with the return CS descriptor;
|
|
Load the SS register with the return SS descriptor;
|
|
For each of ES, FS, GS, and DS
|
|
DO
|
|
IF the current register setting is not valid for the outer level,
|
|
set the register to null (selector AR 0);
|
|
To be valid, the register setting must satisfy the following
|
|
properties:
|
|
Selector index must be within descriptor table limits;
|
|
Descriptor AR byte must indicate data or readable code segment;
|
|
IF segment is data or non-conforming code, THEN
|
|
DPL must be ò CPL, or DPL must be ò RPL;
|
|
FI;
|
|
OD;
|
|
|
|
Description
|
|
|
|
RET transfers control to a return address located on the stack. The
|
|
address is usually placed on the stack by a CALL instruction, and the
|
|
return is made to the instruction that follows the CALL.
|
|
|
|
The optional numeric parameter to RET gives the number of stack bytes
|
|
(OperandMode=16) or words (OperandMode=32) to be released after the return
|
|
address is popped. These items are typically used as input parameters to the
|
|
procedure called.
|
|
|
|
For the intrasegment (near) return, the address on the stack is a segment
|
|
offset, which is popped into the instruction pointer. The CS register is
|
|
unchanged. For the intersegment (far) return, the address on the stack
|
|
is a long pointer. The offset is popped first, followed by the selector.
|
|
|
|
In real mode, CS and IP are loaded directly. In Protected Mode, an
|
|
intersegment return causes the processor to check the descriptor
|
|
addressed by the return selector. The AR byte of the descriptor must
|
|
indicate a code segment of equal or lesser privilege (or greater or equal
|
|
numeric value) than the current privilege level. Returns to a lesser
|
|
privilege level cause the stack to be reloaded from the value saved beyond
|
|
the parameter block.
|
|
|
|
The DS, ES, FS, and GS segment registers can be set to 0 by the RET
|
|
instruction during an interlevel transfer. If these registers refer to
|
|
segments that cannot be used by the new privilege level, they are set to
|
|
0 to prevent unauthorized access from the new privilege level.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP, #NP, or #SS, as described under "Operation" above; #PF(fault-code) for
|
|
a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would be outside the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
|
|
fault
|
|
|
|
|
|
SAHF ÄÄ Store AH into Flags
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
9E SAHF 3 Store AH into flags SF ZF xx AF xx PF xx CF
|
|
|
|
|
|
Operation
|
|
|
|
SF:ZF:xx:AF:xx:PF:xx:CF AH;
|
|
|
|
Description
|
|
|
|
SAHF loads the flags listed above with values from the AH register,
|
|
from bits 7, 6, 4, 2, and 0, respectively.
|
|
|
|
Flags Affected
|
|
|
|
SF, ZF, AF, PF, and CF as described above
|
|
|
|
Protected Mode Exceptions
|
|
|
|
None
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
None
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
None
|
|
|
|
|
|
SAL/SAR/SHL/SHR ÄÄ Shift Instructions
|
|
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
D0 /4 SAL r/m8,1 3/7 Multiply r/m byte by 2, once
|
|
D2 /4 SAL r/m8,CL 3/7 Multiply r/m byte by 2, CL times
|
|
C0 /4 ib SAL r/m8,imm8 3/7 Multiply r/m byte by 2, imm8
|
|
times
|
|
D1 /4 SAL r/m16,1 3/7 Multiply r/m word by 2, once
|
|
D3 /4 SAL r/m16,CL 3/7 Multiply r/m word by 2, CL times
|
|
C1 /4 ib SAL r/m16,imm8 3/7 Multiply r/m word by 2, imm8
|
|
times
|
|
D1 /4 SAL r/m32,1 3/7 Multiply r/m dword by 2, once
|
|
D3 /4 SAL r/m32,CL 3/7 Multiply r/m dword by 2, CL
|
|
times
|
|
C1 /4 ib SAL r/m32,imm8 3/7 Multiply r/m dword by 2, imm8
|
|
times
|
|
D0 /7 SAR r/m8,1 3/7 Signed divide^(1) r/m byte by 2,
|
|
once
|
|
D2 /7 SAR r/m8,CL 3/7 Signed divide^(1) r/m byte by 2,
|
|
CL times
|
|
C0 /7 ib SAR r/m8,imm8 3/7 Signed divide^(1) r/m byte by 2,
|
|
imm8 times
|
|
D1 /7 SAR r/m16,1 3/7 Signed divide^(1) r/m word by 2,
|
|
once
|
|
D3 /7 SAR r/m16,CL 3/7 Signed divide^(1) r/m word by 2,
|
|
CL times
|
|
C1 /7 ib SAR r/m16,imm8 3/7 Signed divide^(1) r/m word by 2,
|
|
imm8 times
|
|
D1 /7 SAR r/m32,1 3/7 Signed divide^(1) r/m dword by 2,
|
|
once
|
|
D3 /7 SAR r/m32,CL 3/7 Signed divide^(1) r/m dword by 2,
|
|
CL times
|
|
C1 /7 ib SAR r/m32,imm8 3/7 Signed divide^(1) r/m dword by 2,
|
|
imm8 times
|
|
D0 /4 SHL r/m8,1 3/7 Multiply r/m byte by 2, once
|
|
D2 /4 SHL r/m8,CL 3/7 Multiply r/m byte by 2, CL times
|
|
C0 /4 ib SHL r/m8,imm8 3/7 Multiply r/m byte by 2, imm8
|
|
times
|
|
D1 /4 SHL r/m16,1 3/7 Multiply r/m word by 2, once
|
|
D3 /4 SHL r/m16,CL 3/7 Multiply r/m word by 2, CL times
|
|
C1 /4 ib SHL r/m16,imm8 3/7 Multiply r/m word by 2, imm8
|
|
times
|
|
D1 /4 SHL r/m32,1 3/7 Multiply r/m dword by 2, once
|
|
D3 /4 SHL r/m32,CL 3/7 Multiply r/m dword by 2, CL
|
|
times
|
|
C1 /4 ib SHL r/m32,imm8 3/7 Multiply r/m dword by 2, imm8
|
|
times
|
|
D0 /5 SHR r/m8,1 3/7 Unsigned divide r/m byte by 2,
|
|
once
|
|
D2 /5 SHR r/m8,CL 3/7 Unsigned divide r/m byte by 2,
|
|
CL times
|
|
C0 /5 ib SHR r/m8,imm8 3/7 Unsigned divide r/m byte by 2,
|
|
imm8 times
|
|
D1 /5 SHR r/m16,1 3/7 Unsigned divide r/m word by 2,
|
|
once
|
|
D3 /5 SHR r/m16,CL 3/7 Unsigned divide r/m word by 2,
|
|
CL times
|
|
C1 /5 ib SHR r/m16,imm8 3/7 Unsigned divide r/m word by 2,
|
|
imm8 times
|
|
D1 /5 SHR r/m32,1 3/7 Unsigned divide r/m dword by 2,
|
|
once
|
|
D3 /5 SHR r/m32,CL 3/7 Unsigned divide r/m dword by 2,
|
|
CL times
|
|
C1 /5 ib SHR r/m32,imm8 3/7 Unsigned divide r/m dword by 2,
|
|
imm8 times
|
|
|
|
|
|
Not the same division as IDIV; rounding is toward negative infinity.
|
|
|
|
Operation
|
|
|
|
(* COUNT is the second parameter *)
|
|
(temp) COUNT;
|
|
WHILE (temp <> 0)
|
|
DO
|
|
IF instruction is SAL or SHL
|
|
THEN CF high-order bit of r/m;
|
|
FI;
|
|
IF instruction is SAR or SHR
|
|
THEN CF low-order bit of r/m;
|
|
FI;
|
|
IF instruction = SAL or SHL
|
|
THEN r/m r/m * 2;
|
|
FI;
|
|
IF instruction = SAR
|
|
THEN r/m r/m /2 (*Signed divide, rounding toward negative infinity*);
|
|
FI;
|
|
IF instruction = SHR
|
|
THEN r/m r/m / 2; (* Unsigned divide *);
|
|
FI;
|
|
temp temp - 1;
|
|
OD;
|
|
(* Determine overflow for the various instructions *)
|
|
IF COUNT = 1
|
|
THEN
|
|
IF instruction is SAL or SHL
|
|
THEN OF high-order bit of r/m <> (CF);
|
|
FI;
|
|
IF instruction is SAR
|
|
THEN OF 0;
|
|
FI;
|
|
IF instruction is SHR
|
|
THEN OF high-order bit of operand;
|
|
FI;
|
|
ELSE OF undefined;
|
|
FI;
|
|
|
|
Description
|
|
|
|
SAL (or its synonym, SHL) shifts the bits of the operand upward. The
|
|
high-order bit is shifted into the carry flag, and the low-order bit is set
|
|
to 0.
|
|
|
|
SAR and SHR shift the bits of the operand downward. The low-order
|
|
bit is shifted into the carry flag. The effect is to divide the operand by
|
|
2. SAR performs a signed divide with rounding toward negative infinity (not
|
|
the same as IDIV); the high-order bit remains the same. SHR performs an
|
|
unsigned divide; the high-order bit is set to 0.
|
|
|
|
The shift is repeated the number of times indicated by the second
|
|
operand, which is either an immediate number or the contents of the CL
|
|
register. To reduce the maximum execution time, the 80386 does not
|
|
allow shift counts greater than 31. If a shift count greater than 31 is
|
|
attempted, only the bottom five bits of the shift count are used. (The
|
|
8086 uses all eight bits of the shift count.)
|
|
|
|
The overflow flag is set only if the single-shift forms of the instructions
|
|
are used. For left shifts, OF is set to 0 if the high bit of the answer is
|
|
the same as the result of the carry flag (i.e., the top two bits of the
|
|
original operand were the same); OF is set to 1 if they are different. For
|
|
SAR, OF is set to 0 for all single shifts. For SHR, OF is set to the
|
|
high-order bit of the original operand.
|
|
|
|
Flags Affected
|
|
|
|
OF for single shifts; OF is undefined for multiple shifts; CF, ZF, PF,
|
|
and SF as described in Appendix C
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
|
|
memory operand effective address in the CS, DS, ES, FS, or GS
|
|
segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code)
|
|
for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
|
|
fault
|
|
|
|
|
|
SBB ÄÄ Integer Subtraction with Borrow
|
|
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
1C ib SBB AL,imm8 2 Subtract with borrow immediate byte
|
|
from AL
|
|
1D iw SBB AX,imm16 2 Subtract with borrow immediate word
|
|
from AX
|
|
1D id SBB EAX,imm32 2 Subtract with borrow immediate
|
|
dword from EAX
|
|
80 /3 ib SBB r/m8,imm8 2/7 Subtract with borrow immediate byte
|
|
from r/m byte
|
|
81 /3 iw SBB r/m16,imm16 2/7 Subtract with borrow immediate word
|
|
from r/m word
|
|
81 /3 id SBB r/m32,imm32 2/7 Subtract with borrow immediate
|
|
dword from r/m dword
|
|
83 /3 ib SBB r/m16,imm8 2/7 Subtract with borrow sign-extended
|
|
immediate byte from r/m word
|
|
83 /3 ib SBB r/m32,imm8 2/7 Subtract with borrow sign-extended
|
|
immediate byte from r/m dword
|
|
18 /r SBB r/m8,r8 2/6 Subtract with borrow byte register
|
|
from r/m byte
|
|
19 /r SBB r/m16,r16 2/6 Subtract with borrow word register
|
|
from r/m word
|
|
19 /r SBB r/m32,r32 2/6 Subtract with borrow dword register
|
|
from r/m dword
|
|
1A /r SBB r8,r/m8 2/7 Subtract with borrow byte register
|
|
from r/m byte
|
|
1B /r SBB r16,r/m16 2/7 Subtract with borrow word register
|
|
from r/m word
|
|
1B /r SBB r32,r/m32 2/7 Subtract with borrow dword register
|
|
from r/m dword
|
|
|
|
|
|
Operation
|
|
|
|
IF SRC is a byte and DEST is a word or dword
|
|
THEN DEST = DEST - (SignExtend(SRC) + CF)
|
|
ELSE DEST DEST - (SRC + CF);
|
|
|
|
Description
|
|
|
|
SBB adds the second operand (DEST) to the carry flag (CF) and
|
|
subtracts the result from the first operand (SRC). The result of the
|
|
subtraction is assigned to the first operand (DEST), and the flags are
|
|
set accordingly.
|
|
|
|
When an immediate byte value is subtracted from a word operand, the
|
|
immediate value is first sign-extended.
|
|
|
|
Flags Affected
|
|
|
|
OF, SF, ZF, AF, PF, and CF as described in Appendix C
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
|
|
memory operand effective address in the CS, DS, ES, FS, or GS
|
|
segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code)
|
|
for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
|
|
fault
|
|
|
|
|
|
SCAS/SCASB/SCASW/SCASD ÄÄ Compare String Data
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
AE SCAS m8 7 Compare bytes AL-ES:[DI], update (E)DI
|
|
AF SCAS m16 7 Compare words AX-ES:[DI], update (E)DI
|
|
AF SCAS m32 7 Compare dwords EAX-ES:[DI], update (E)DI
|
|
AE SCASB 7 Compare bytes AL-ES:[DI], update (E)DI
|
|
AF SCASW 7 Compare words AX-ES:[DI], update (E)DI
|
|
AF SCASD 7 Compare dwords EAX-ES:[DI], update (E)DI
|
|
|
|
|
|
Operation
|
|
|
|
IF AddressSize = 16
|
|
THEN use DI for dest-index;
|
|
ELSE (* AddressSize = 32 *) use EDI for dest-index;
|
|
FI;
|
|
IF byte type of instruction
|
|
THEN
|
|
AL - [dest-index]; (* Compare byte in AL and dest *)
|
|
IF DF = 0 THEN IndDec 1 ELSE IncDec -1; FI;
|
|
ELSE
|
|
IF OperandSize = 16
|
|
THEN
|
|
AX - [dest-index]; (* compare word in AL and dest *)
|
|
IF DF = 0 THEN IncDec 2 ELSE IncDec -2; FI;
|
|
ELSE (* OperandSize = 32 *)
|
|
EAX - [dest-index];(* compare dword in EAX & dest *)
|
|
IF DF = 0 THEN IncDec 4 ELSE IncDec -4; FI;
|
|
FI;
|
|
FI;
|
|
dest-index = dest-index + IncDec
|
|
|
|
Description
|
|
|
|
SCAS subtracts the memory byte or word at the destination register from
|
|
the AL, AX or EAX register. The result is discarded; only the flags are set.
|
|
The operand must be addressable from the ES segment; no segment override is
|
|
possible.
|
|
|
|
If the address-size attribute for this instruction is 16 bits, DI is used
|
|
as the destination register; otherwise, the address-size attribute is 32
|
|
bits and EDI is used.
|
|
|
|
The address of the memory data being compared is determined solely by the
|
|
contents of the destination register, not by the operand to SCAS. The
|
|
operand validates ES segment addressability and determines the data type.
|
|
Load the correct index value into DI or EDI before executing SCAS.
|
|
|
|
After the comparison is made, the destination register is automatically
|
|
updated. If the direction flag is 0 (CLD was executed), the destination
|
|
register is incremented; if the direction flag is 1 (STD was executed), it
|
|
is decremented. The increments or decrements are by 1 if bytes are compared,
|
|
by 2 if words are compared, or by 4 if doublewords are compared.
|
|
|
|
SCASB, SCASW, and SCASD are synonyms for the byte, word and
|
|
doubleword SCAS instructions that don't require operands. They are
|
|
simpler to code, but provide no type or segment checking.
|
|
|
|
SCAS can be preceded by the REPE or REPNE prefix for a block search
|
|
of CX or ECX bytes or words. Refer to the REP instruction for further
|
|
details.
|
|
|
|
Flags Affected
|
|
|
|
OF, SF, ZF, AF, PF, and CF as described in Appendix C
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) for an illegal memory operand effective address in the CS, DS,
|
|
ES, FS, or GS segments; #SS(0) for an illegal address in the SS segment;
|
|
#PF(fault-code) for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
|
|
fault
|
|
|
|
|
|
SETcc ÄÄ Byte Set on Condition
|
|
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
0F 97 SETA r/m8 4/5 Set byte if above (CF=0 and ZF=0)
|
|
0F 93 SETAE r/m8 4/5 Set byte if above or equal (CF=0)
|
|
0F 92 SETB r/m8 4/5 Set byte if below (CF=1)
|
|
0F 96 SETBE r/m8 4/5 Set byte if below or equal (CF=1 or (ZF=1)
|
|
0F 92 SETC r/m8 4/5 Set if carry (CF=1)
|
|
0F 94 SETE r/m8 4/5 Set byte if equal (ZF=1)
|
|
0F 9F SETG r/m8 4/5 Set byte if greater (ZF=0 or SF=OF)
|
|
0F 9D SETGE r/m8 4/5 Set byte if greater or equal (SF=OF)
|
|
0F 9C SETL r/m8 4/5 Set byte if less (SF<>OF)
|
|
0F 9E SETLE r/m8 4/5 Set byte if less or equal (ZF=1 and
|
|
SF<>OF)
|
|
0F 96 SETNA r/m8 4/5 Set byte if not above (CF=1)
|
|
0F 92 SETNAE r/m8 4/5 Set byte if not above or equal (CF=1)
|
|
0F 93 SETNB r/m8 4/5 Set byte if not below (CF=0)
|
|
0F 97 SETNBE r/m8 4/5 Set byte if not below or equal (CF=0 and
|
|
ZF=0)
|
|
0F 93 SETNC r/m8 4/5 Set byte if not carry (CF=0)
|
|
0F 95 SETNE r/m8 4/5 Set byte if not equal (ZF=0)
|
|
0F 9E SETNG r/m8 4/5 Set byte if not greater (ZF=1 or SF<>OF)
|
|
0F 9C SETNGE r/m8 4/5 Set if not greater or equal (SF<>OF)
|
|
0F 9D SETNL r/m8 4/5 Set byte if not less (SF=OF)
|
|
0F 9F SETNLE r/m8 4/5 Set byte if not less or equal (ZF=1 and
|
|
SF<>OF)
|
|
0F 91 SETNO r/m8 4/5 Set byte if not overflow (OF=0)
|
|
0F 9B SETNP r/m8 4/5 Set byte if not parity (PF=0)
|
|
0F 99 SETNS r/m8 4/5 Set byte if not sign (SF=0)
|
|
0F 95 SETNZ r/m8 4/5 Set byte if not zero (ZF=0)
|
|
0F 90 SETO r/m8 4/5 Set byte if overflow (OF=1)
|
|
0F 9A SETP r/m8 4/5 Set byte if parity (PF=1)
|
|
0F 9A SETPE r/m8 4/5 Set byte if parity even (PF=1)
|
|
0F 9B SETPO r/m8 4/5 Set byte if parity odd (PF=0)
|
|
0F 98 SETS r/m8 4/5 Set byte if sign (SF=1)
|
|
0F 94 SETZ r/m8 4/5 Set byte if zero (ZF=1)
|
|
|
|
|
|
Operation
|
|
|
|
IF condition THEN r/m8 1 ELSE r/m8 0; FI;
|
|
|
|
Description
|
|
|
|
SETcc stores a byte at the destination specified by the effective address
|
|
or register if the condition is met, or a 0 byte if the condition is not
|
|
met.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the result is in a non-writable segment; #GP(0) for an illegal
|
|
memory operand effective address in the CS, DS, ES, FS, or GS segments;
|
|
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page
|
|
fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
|
|
fault
|
|
|
|
|
|
SGDT/SIDT ÄÄ Store Global/Interrupt Descriptor Table Register
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
0F 01 /0 SGDT m 9 Store GDTR to m
|
|
0F 01 /1 SIDT m 9 Store IDTR to m
|
|
|
|
|
|
Operation
|
|
|
|
DEST 48-bit BASE/LIMIT register contents;
|
|
|
|
Description
|
|
|
|
SGDT/SIDT copies the contents of the descriptor table register the six
|
|
bytes of memory indicated by the operand. The LIMIT field of the
|
|
register is assigned to the first word at the effective address. If the
|
|
operand-size attribute is 32 bits, the next three bytes are assigned the
|
|
BASE field of the register, and the fourth byte is written with zero. The
|
|
last byte is undefined. Otherwise, if the operand-size attribute is 16
|
|
bits, the next four bytes are assigned the 32-bit BASE field of the
|
|
register.
|
|
|
|
SGDT and SIDT are used only in operating system software; they are
|
|
not used in application programs.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
Interrupt 6 if the destination operand is a register; #GP(0) if the
|
|
destination is in a nonwritable segment; #GP(0) for an illegal memory
|
|
operand effective address in the CS, DS, ES, FS, or GS segments; #SS(0) for
|
|
an illegal address in the SS segment; #PF(fault-code) for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 6 if the destination operand is a register; Interrupt 13 if any
|
|
part of the operand would lie outside of the effective address space from
|
|
0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
|
|
fault
|
|
|
|
Compatability Note
|
|
|
|
The 16-bit forms of the SGDT/SIDT instructions are compatible with
|
|
the 80286, if the value in the upper eight bits is not referenced. The
|
|
80286 stores 1's in these upper bits, whereas the 80386 stores 0's if the
|
|
operand-size attribute is 16 bits. These bits were specified as undefined
|
|
by the SGDT/SIDT instructions in the iAPX 286 Programmer's
|
|
Reference Manual.
|
|
|
|
|
|
SHLD ÄÄ Double Precision Shift Left
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
0F A4 SHLD r/m16,r16,imm8 3/7 r/m16 gets SHL of r/m16 concatenated
|
|
with r16
|
|
0F A4 SHLD r/m32,r32,imm8 3/7 r/m32 gets SHL of r/m32 concatenated
|
|
with r32
|
|
0F A5 SHLD r/m16,r16,CL 3/7 r/m16 gets SHL of r/m16 concatenated
|
|
with r16
|
|
0F A5 SHLD r/m32,r32,CL 3/7 r/m32 gets SHL of r/m32 concatenated
|
|
with r32
|
|
|
|
|
|
Operation
|
|
|
|
(* count is an unsigned integer corresponding to the last operand of the
|
|
instruction, either an immediate byte or the byte in register CL *)
|
|
ShiftAmt count MOD 32;
|
|
inBits register; (* Allow overlapped operands *)
|
|
IF ShiftAmt = 0
|
|
THEN no operation
|
|
ELSE
|
|
IF ShiftAmt ò OperandSize
|
|
THEN (* Bad parameters *)
|
|
r/m UNDEFINED;
|
|
CF, OF, SF, ZF, AF, PF UNDEFINED;
|
|
ELSE (* Perform the shift *)
|
|
CF BIT[Base, OperandSize - ShiftAmt];
|
|
(* Last bit shifted out on exit *)
|
|
FOR i OperandSize - 1 DOWNTO ShiftAmt
|
|
DO
|
|
BIT[Base, i] BIT[Base, i - ShiftAmt];
|
|
OF;
|
|
FOR i ShiftAmt - 1 DOWNTO 0
|
|
DO
|
|
BIT[Base, i] BIT[inBits, i - ShiftAmt + OperandSize];
|
|
OD;
|
|
Set SF, ZF, PF (r/m);
|
|
(* SF, ZF, PF are set according to the value of the result *)
|
|
AF UNDEFINED;
|
|
FI;
|
|
FI;
|
|
|
|
Description
|
|
|
|
SHLD shifts the first operand provided by the r/m field to the left as
|
|
many bits as specified by the count operand. The second operand (r16 or r32)
|
|
provides the bits to shift in from the right (starting with bit 0). The
|
|
result is stored back into the r/m operand. The register remains unaltered.
|
|
|
|
The count operand is provided by either an immediate byte or the contents
|
|
of the CL register. These operands are taken MODULO 32 to provide a number
|
|
between 0 and 31 by which to shift. Because the bits to shift are provided
|
|
by the specified registers, the operation is useful for multiprecision
|
|
shifts (64 bits or more). The SF, ZF and PF flags are set according to the
|
|
value of the result. CS is set to the value of the last bit shifted out. OF
|
|
and AF are left undefined.
|
|
|
|
Flags Affected
|
|
|
|
OF, SF, ZF, PF, and CF as described above; AF and OF are undefined
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
|
|
memory operand effective address in the CS, DS, ES, FS, or GS segments;
|
|
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page
|
|
fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
|
|
|
|
|
|
SHRD ÄÄ Double Precision Shift Right
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
0F AC SHRD r/m16,r16,imm8 3/7 r/m16 gets SHR of r/m16 concatenated
|
|
with r16
|
|
0F AC SHRD r/m32,r32,imm8 3/7 r/m32 gets SHR of r/m32 concatenated
|
|
with r32
|
|
0F AD SHRD r/m16,r16,CL 3/7 r/m16 gets SHR of r/m16 concatenated
|
|
with r16
|
|
0F AD SHRD r/m32,r32,CL 3/7 r/m32 gets SHR of r/m32 concatenated
|
|
with r32
|
|
|
|
|
|
Operation
|
|
|
|
(* count is an unsigned integer corresponding to the last operand of the
|
|
instruction, either an immediate byte or the byte in register CL *)
|
|
ShiftAmt count MOD 32;
|
|
inBits register; (* Allow overlapped operands *)
|
|
IF ShiftAmt = 0
|
|
THEN no operation
|
|
ELSE
|
|
IF ShiftAmt ò OperandSize
|
|
THEN (* Bad parameters *)
|
|
r/m UNDEFINED;
|
|
CF, OF, SF, ZF, AF, PF UNDEFINED;
|
|
ELSE (* Perform the shift *)
|
|
CF BIT[r/m, ShiftAmt - 1]; (* last bit shifted out on exit *)
|
|
FOR i 0 TO OperandSize - 1 - ShiftAmt
|
|
DO
|
|
BIT[r/m, i] BIT[r/m, i - ShiftAmt];
|
|
OD;
|
|
FOR i OperandSize - ShiftAmt TO OperandSize - 1
|
|
DO
|
|
BIT[r/m,i] BIT[inBits,i+ShiftAmt - OperandSize];
|
|
OD;
|
|
Set SF, ZF, PF (r/m);
|
|
(* SF, ZF, PF are set according to the value of the result *)
|
|
Set SF, ZF, PF (r/m);
|
|
AF UNDEFINED;
|
|
FI;
|
|
FI;
|
|
|
|
Description
|
|
|
|
SHRD shifts the first operand provided by the r/m field to the right as many
|
|
bits as specified by the count operand. The second operand (r16 or r32)
|
|
provides the bits to shift in from the left (starting with bit 31). The
|
|
result is stored back into the r/m operand. The register remains unaltered.
|
|
|
|
The count operand is provided by either an immediate byte or the contents
|
|
of the CL register. These operands are taken MODULO 32 to provide a number
|
|
between 0 and 31 by which to shift. Because the bits to shift are provided
|
|
by the specified register, the operation is useful for multi-precision
|
|
shifts (64 bits or more). The SF, ZF and PF flags are set according to the
|
|
value of the result. CS is set to the value of the last bit shifted out. OF
|
|
and AF are left undefined.
|
|
|
|
Flags Affected
|
|
|
|
OF, SF, ZF, PF, and CF as described above; AF and OF are undefined
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
|
|
memory operand effective address in the CS, DS, ES, FS, or GS
|
|
segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code)
|
|
for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
|
|
fault
|
|
|
|
|
|
SLDT ÄÄ Store Local Descriptor Table Register
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
0F 00 /0 SLDT r/m16 pm=2/2 Store LDTR to EA word
|
|
|
|
|
|
Operation
|
|
|
|
r/m16 LDTR;
|
|
|
|
Description
|
|
|
|
SLDT stores the Local Descriptor Table Register (LDTR) in the two-byte
|
|
register or memory location indicated by the effective address operand.
|
|
This register is a selector that points into the Global Descriptor Table.
|
|
|
|
SLDT is used only in operating system software. It is not used in
|
|
application programs.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
|
|
memory operand effective address in the CS, DS, ES, FS, or GS segments;
|
|
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page
|
|
fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 6; SLDT is not recognized in Real Address Mode
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
|
|
|
|
Notes
|
|
|
|
The operand-size attribute has no effect on the operation of the
|
|
instruction.
|
|
|
|
|
|
SMSW ÄÄ Store Machine Status Word
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
0F 01 /4 SMSW r/m16 2/3,pm=2/2 Store machine status word to EA
|
|
word
|
|
|
|
|
|
Operation
|
|
|
|
r/m16 MSW;
|
|
|
|
Description
|
|
|
|
SMSW stores the machine status word (part of CR0) in the two-byte register
|
|
or memory location indicated by the effective address operand.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
|
|
memory operand effective address in the CS, DS, ES, FS, or GS segments;
|
|
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page
|
|
fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
|
|
|
|
Notes
|
|
|
|
This instruction is provided for compatibility with the 80286; 80386
|
|
programs should use MOV ..., CR0.
|
|
|
|
|
|
STC ÄÄ Set Carry Flag
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
F9 STC 2 Set carry flag
|
|
|
|
|
|
Operation
|
|
|
|
CF 1;
|
|
|
|
Description
|
|
|
|
STC sets the carry flag to 1.
|
|
|
|
Flags Affected
|
|
|
|
CF = 1
|
|
|
|
Protected Mode Exceptions
|
|
|
|
None
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
None
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
None
|
|
|
|
|
|
STD ÄÄ Set Direction Flag
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
FD STD 2 Set direction flag so (E)SI and/or (E)DI
|
|
decrement
|
|
|
|
|
|
Operation
|
|
|
|
DF 1;
|
|
|
|
Description
|
|
|
|
STD sets the direction flag to 1, causing all subsequent string operations
|
|
to decrement the index registers, (E)SI and/or (E)DI, on which they
|
|
operate.
|
|
|
|
Flags Affected
|
|
|
|
DF = 1
|
|
|
|
Protected Mode Exceptions
|
|
|
|
None
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
None
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
None
|
|
|
|
|
|
STI ÄÄ Set Interrupt Flag
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
F13 STI 3 Set interrupt flag; interrupts enabled at the
|
|
end of the next instruction
|
|
|
|
|
|
Operation
|
|
|
|
IF 1
|
|
|
|
Description
|
|
|
|
STI sets the interrupt flag to 1. The 80386 then responds to external
|
|
interrupts after executing the next instruction if the next instruction
|
|
allows the interrupt flag to remain enabled. If external interrupts are
|
|
disabled and you code STI, RET (such as at the end of a subroutine),
|
|
the RET is allowed to execute before external interrupts are recognized.
|
|
Also, if external interrupts are disabled and you code STI, CLI, then
|
|
external interrupts are not recognized because the CLI instruction clears
|
|
the interrupt flag during its execution.
|
|
|
|
Flags Affected
|
|
|
|
IF = 1
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the current privilege level is greater (has less privilege) than
|
|
the I/O privilege level
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
None
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
None
|
|
|
|
|
|
STOS/STOSB/STOSW/STOSD ÄÄ Store String Data
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
AA STOS m8 4 Store AL in byte ES:[(E)DI], update (E)DI
|
|
AB STOS m16 4 Store AX in word ES:[(E)DI], update (E)DI
|
|
AB STOS m32 4 Store EAX in dword ES:[(E)DI], update (E)DI
|
|
AA STOSB 4 Store AL in byte ES:[(E)DI], update (E)DI
|
|
AB STOSW 4 Store AX in word ES:[(E)DI], update (E)DI
|
|
AB STOSD 4 Store EAX in dword ES:[(E)DI], update (E)DI
|
|
|
|
|
|
Operation
|
|
|
|
IF AddressSize = 16
|
|
THEN use ES:DI for DestReg
|
|
ELSE (* AddressSize = 32 *) use ES:EDI for DestReg;
|
|
FI;
|
|
IF byte type of instruction
|
|
THEN
|
|
(ES:DestReg) AL;
|
|
IF DF = 0
|
|
THEN DestReg DestReg + 1;
|
|
ELSE DestReg DestReg - 1;
|
|
FI;
|
|
ELSE IF OperandSize = 16
|
|
THEN
|
|
(ES:DestReg) AX;
|
|
IF DF = 0
|
|
THEN DestReg DestReg + 2;
|
|
ELSE DestReg DestReg - 2;
|
|
FI;
|
|
ELSE (* OperandSize = 32 *)
|
|
(ES:DestReg) EAX;
|
|
IF DF = 0
|
|
THEN DestReg DestReg + 4;
|
|
ELSE DestReg DestReg - 4;
|
|
FI;
|
|
FI;
|
|
FI;
|
|
|
|
Description
|
|
|
|
STOS transfers the contents of all AL, AX, or EAX register to the memory
|
|
byte or word given by the destination register relative to the ES segment.
|
|
The destination register is DI for an address-size attribute of 16 bits or
|
|
EDI for an address-size attribute of 32 bits.
|
|
|
|
The destination operand must be addressable from the ES register. A segment
|
|
override is not possible.
|
|
|
|
The address of the destination is determined by the contents of the
|
|
destination register, not by the explicit operand of STOS. This operand is
|
|
used only to validate ES segment addressability and to determine the data
|
|
type. Load the correct index value into the destination register before
|
|
executing STOS.
|
|
|
|
After the transfer is made, DI is automatically updated. If the direction
|
|
flag is 0 (CLD was executed), DI is incremented; if the direction flag is
|
|
1 (STD was executed), DI is decremented. DI is incremented or decremented by
|
|
1 if a byte is stored, by 2 if a word is stored, or by 4 if a doubleword is
|
|
stored.
|
|
|
|
STOSB, STOSW, and STOSD are synonyms for the byte, word, and doubleword STOS
|
|
instructions, that do not require an operand. They are simpler to use, but
|
|
provide no type or segment checking.
|
|
|
|
STOS can be preceded by the REP prefix for a block fill of CX or ECX bytes,
|
|
words, or doublewords. Refer to the REP instruction for further details.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
|
|
memory operand effective address in the CS, DS, ES, FS, or GS segments;
|
|
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page
|
|
fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
|
|
|
|
|
|
STR ÄÄ Store Task Register
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
0F 00 /1 STR r/m16 pm=23/27 Load EA word into task register
|
|
|
|
|
|
Operation
|
|
|
|
r/m task register;
|
|
|
|
Description
|
|
|
|
The contents of the task register are copied to the two-byte register or
|
|
memory location indicated by the effective address operand.
|
|
|
|
STR is used only in operating system software. It is not used in application
|
|
programs.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
|
|
memory operand effective address in the CS, DS, ES, FS, or GS segments;
|
|
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page
|
|
fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 6; STR is not recognized in Real Address Mode
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode
|
|
|
|
Notes
|
|
|
|
The operand-size attribute has no effect on this instruction.
|
|
|
|
|
|
SUB ÄÄ Integer Subtraction
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
2C ib SUB AL,imm8 2 Subtract immediate byte from AL
|
|
2D iw SUB AX,imm16 2 Subtract immediate word from AX
|
|
2D id SUB EAX,imm32 2 Subtract immediate dword from EAX
|
|
80 /5 ib SUB r/m8,imm8 2/7 Subtract immediate byte from r/m byte
|
|
81 /5 iw SUB r/m16,imm16 2/7 Subtract immediate word from r/m word
|
|
81 /5 id SUB r/m32,imm32 2/7 Subtract immediate dword from r/m
|
|
dword
|
|
83 /5 ib SUB r/m16,imm8 2/7 Subtract sign-extended immediate byte
|
|
from r/m word
|
|
83 /5 ib SUB r/m32,imm8 2/7 Subtract sign-extended immediate byte
|
|
from r/m dword
|
|
28 /r SUB r/m8,r8 2/6 Subtract byte register from r/m byte
|
|
29 /r SUB r/m16,r16 2/6 Subtract word register from r/m word
|
|
29 /r SUB r/m32,r32 2/6 Subtract dword register from r/m
|
|
dword
|
|
2A /r SUB r8,r/m8 2/7 Subtract byte register from r/m byte
|
|
2B /r SUB r16,r/m16 2/7 Subtract word register from r/m word
|
|
2B /r SUB r32,r/m32 2/7 Subtract dword register from r/m
|
|
dword
|
|
|
|
|
|
Operation
|
|
|
|
IF SRC is a byte and DEST is a word or dword
|
|
THEN DEST = DEST - SignExtend(SRC);
|
|
ELSE DEST DEST - SRC;
|
|
FI;
|
|
|
|
Description
|
|
|
|
SUB subtracts the second operand (SRC) from the first operand (DEST). The
|
|
first operand is assigned the result of the subtraction, and the flags are
|
|
set accordingly.
|
|
|
|
When an immediate byte value is subtracted from a word operand, the
|
|
immediate value is first sign-extended to the size of the destination
|
|
operand.
|
|
|
|
Flags Affected
|
|
|
|
OF, SF, ZF, AF, PF, and CF as described in Appendix C
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
|
|
memory operand effective address in the CS, DS, ES, FS, or GS segments;
|
|
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page
|
|
fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
|
|
|
|
|
|
TEST ÄÄ Logical Compare
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
A8 ib TEST AL,imm8 2 AND immediate byte with AL
|
|
A9 iw TEST AX,imm16 2 AND immediate word with AX
|
|
A9 id TEST EAX,imm32 2 AND immediate dword with EAX
|
|
F6 /0 ib TEST r/m8,imm8 2/5 AND immediate byte with r/m byte
|
|
F7 /0 iw TEST r/m16,imm16 2/5 AND immediate word with r/m word
|
|
F7 /0 id TEST r/m32,imm32 2/5 AND immediate dword with r/m dword
|
|
84 /r TEST r/m8,r8 2/5 AND byte register with r/m byte
|
|
85 /r TEST r/m16,r16 2/5 AND word register with r/m word
|
|
85 /r TEST r/m32,r32 2/5 AND dword register with r/m dword
|
|
|
|
|
|
Operation
|
|
|
|
DEST : = LeftSRC AND RightSRC;
|
|
CF 0;
|
|
OF 0;
|
|
|
|
Description
|
|
|
|
TEST computes the bit-wise logical AND of its two operands. Each bit
|
|
of the result is 1 if both of the corresponding bits of the operands are 1;
|
|
otherwise, each bit is 0. The result of the operation is discarded and only
|
|
the flags are modified.
|
|
|
|
Flags Affected
|
|
|
|
OF = 0, CF = 0; SF, ZF, and PF as described in Appendix C
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) for an illegal memory operand effective address in the CS, DS,
|
|
ES, FS, or GS segments; #SS(0) for an illegal address in the SS segment;
|
|
#PF(fault-code) for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
|
|
fault
|
|
|
|
|
|
VERR, VERW ÄÄ Verify a Segment for Reading or Writing
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
0F 00 /4 VERR r/m16 pm=10/11 Set ZF=1 if segment can be read,
|
|
selector in r/m16
|
|
0F 00 /5 VERW r/m16 pm=15/16 Set ZF=1 if segment can be written,
|
|
selector in r/m16
|
|
|
|
|
|
Operation
|
|
|
|
IF segment with selector at (r/m) is accessible
|
|
with current protection level
|
|
AND ((segment is readable for VERR) OR
|
|
(segment is writable for VERW))
|
|
THEN ZF 0;
|
|
ELSE ZF 1;
|
|
FI;
|
|
|
|
Description
|
|
|
|
The two-byte register or memory operand of VERR and VERW contains
|
|
the value of a selector. VERR and VERW determine whether the
|
|
segment denoted by the selector is reachable from the current privilege
|
|
level and whether the segment is readable (VERR) or writable (VERW).
|
|
If the segment is accessible, the zero flag is set to 1; if the segment is
|
|
not accessible, the zero flag is set to 0. To set ZF, the following
|
|
conditions must be met:
|
|
|
|
þ The selector must denote a descriptor within the bounds of the table
|
|
(GDT or LDT); the selector must be "defined."
|
|
|
|
þ The selector must denote the descriptor of a code or data segment
|
|
(not that of a task state segment, LDT, or a gate).
|
|
|
|
þ For VERR, the segment must be readable. For VERW, the segment
|
|
must be a writable data segment.
|
|
|
|
þ If the code segment is readable and conforming, the descriptor
|
|
privilege level (DPL) can be any value for VERR. Otherwise, the
|
|
DPL must be greater than or equal to (have less or the same
|
|
privilege as) both the current privilege level and the selector's RPL.
|
|
|
|
The validation performed is the same as if the segment were loaded into
|
|
DS, ES, FS, or GS, and the indicated access (read or write) were
|
|
performed. The zero flag receives the result of the validation. The
|
|
selector's value cannot result in a protection exception, enabling the
|
|
software to anticipate possible segment access problems.
|
|
|
|
Flags Affected
|
|
|
|
ZF as described above
|
|
|
|
Protected Mode Exceptions
|
|
|
|
Faults generated by illegal addressing of the memory operand that
|
|
contains the selector, the selector is not loaded into any segment
|
|
register, and no faults attributable to the selector operand are generated
|
|
|
|
#GP(0) for an illegal memory operand effective address in the CS, DS,
|
|
ES, FS, or GS segments; #SS(0) for an illegal address in the SS segment;
|
|
#PF(fault-code) for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 6; VERR and VERW are not recognized in Real Address Mode
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
|
|
fault
|
|
|
|
|
|
WAIT ÄÄ Wait until BUSY# Pin is Inactive (HIGH)
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
9B WAIT 6 min. Wait until BUSY pin is inactive (HIGH)
|
|
|
|
|
|
Description
|
|
|
|
WAIT suspends execution of 80386 instructions until the BUSY# pin is
|
|
inactive (high). The BUSY# pin is driven by the 80287 numeric processor
|
|
extension.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#NM if the task-switched flag in the machine status word (the lower 16 bits
|
|
of register CR0) is set; #MF if the ERROR# input pin is asserted (i.e., the
|
|
80287 has detected an unmasked numeric error)
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Same exceptions as in Protected Mode
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Protected Mode
|
|
|
|
|
|
XCHG ÄÄ Exchange Register/Memory with Register
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
90 + r XCHG AX,r16 3 Exchange word register with AX
|
|
90 + r XCHG r16,AX 3 Exchange word register with AX
|
|
90 + r XCHG EAX,r32 3 Exchange dword register with EAX
|
|
90 + r XCHG r32,EAX 3 Exchange dword register with EAX
|
|
86 /r XCHG r/m8,r8 3 Exchange byte register with EA byte
|
|
86 /r XCHG r8,r/m8 3/5 Exchange byte register with EA byte
|
|
87 /r XCHG r/m16,r16 3 Exchange word register with EA word
|
|
87 /r XCHG r16,r/m16 3/5 Exchange word register with EA word
|
|
87 /r XCHG r/m32,r32 3 Exchange dword register with EA dword
|
|
87 /r XCHG r32,r/m32 3/5 Exchange dword register with EA dword
|
|
|
|
|
|
Operation
|
|
|
|
temp DEST
|
|
DEST SRC
|
|
SRC temp
|
|
|
|
Description
|
|
|
|
XCHG exchanges two operands. The operands can be in either order. If a
|
|
memory operand is involved, BUS LOCK is asserted for the duration of the
|
|
exchange, regardless of the presence or absence of the LOCK prefix or of the
|
|
value of the IOPL.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if either operand is in a nonwritable segment; #GP(0) for an
|
|
illegal memory operand effective address in the CS, DS, ES, FS, or GS
|
|
segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code)
|
|
for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
|
|
fault
|
|
|
|
|
|
XLAT/XLATB ÄÄ Table Look-up Translation
|
|
|
|
D7 XLAT m8 5 Set AL to memory byte DS:[(E)BX + unsigned AL]
|
|
D7 XLATB 5 Set AL to memory byte DS:[(E)BX + unsigned AL]
|
|
|
|
|
|
Operation
|
|
|
|
IF AddressSize = 16
|
|
THEN
|
|
AL (BX + ZeroExtend(AL))
|
|
ELSE (* AddressSize = 32 *)
|
|
AL (EBX + ZeroExtend(AL));
|
|
FI;
|
|
|
|
Description
|
|
|
|
XLAT changes the AL register from the table index to the table entry. AL
|
|
should be the unsigned index into a table addressed by DS:BX (for an
|
|
address-size attribute of 16 bits) or DS:EBX (for an address-size attribute
|
|
of 32 bits).
|
|
|
|
The operand to XLAT allows for the possibility of a segment override. XLAT
|
|
uses the contents of BX even if they differ from the offset of the operand.
|
|
The offset of the operand should have been moved intoBX/EBX with a previous
|
|
instruction.
|
|
|
|
The no-operand form, XLATB, can be used if the BX/EBX table will always
|
|
reside in the DS segment.
|
|
|
|
Flags Affected
|
|
|
|
None
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) for an illegal memory operand effective address in the CS, DS, ES,
|
|
FS, or GS segments; #SS(0) for an illegal address in the SS segment;
|
|
#PF(fault-code) for a page fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
|
|
|
|
|
|
XOR ÄÄ Logical Exclusive OR
|
|
|
|
|
|
Opcode Instruction Clocks Description
|
|
|
|
34 ib XOR AL,imm8 2 Exclusive-OR immediate byte to AL
|
|
35 iw XOR AX,imm16 2 Exclusive-OR immediate word to AX
|
|
35 id XOR EAX,imm32 2 Exclusive-OR immediate dword to EAX
|
|
80 /6 ib XOR r/m8,imm8 2/7 Exclusive-OR immediate byte to r/m
|
|
byte
|
|
81 /6 iw XOR r/m16,imm16 2/7 Exclusive-OR immediate word to r/m
|
|
word
|
|
81 /6 id XOR r/m32,imm32 2/7 Exclusive-OR immediate dword to r/m
|
|
dword
|
|
83 /6 ib XOR r/m16,imm8 2/7 XOR sign-extended immediate byte
|
|
with r/m word
|
|
83 /6 ib XOR r/m32,imm8 2/7 XOR sign-extended immediate byte
|
|
with r/m dword
|
|
30 /r XOR r/m8,r8 2/6 Exclusive-OR byte register to r/m
|
|
byte
|
|
31 /r XOR r/m16,r16 2/6 Exclusive-OR word register to r/m
|
|
word
|
|
31 /r XOR r/m32,r32 2/6 Exclusive-OR dword register to r/m
|
|
dword
|
|
32 /r XOR r8,r/m8 2/7 Exclusive-OR byte register to r/m
|
|
byte
|
|
33 /r XOR r16,r/m16 2/7 Exclusive-OR word register to r/m
|
|
word
|
|
33 /r XOR r32,r/m32 2/7 Exclusive-OR dword register to r/m
|
|
dword
|
|
|
|
|
|
Operation
|
|
|
|
DEST LeftSRC XOR RightSRC
|
|
CF 0
|
|
OF 0
|
|
|
|
Description
|
|
|
|
XOR computes the exclusive OR of the two operands. Each bit of the result
|
|
is 1 if the corresponding bits of the operands are different; each bit is 0
|
|
if the corresponding bits are the same. The answer replaces the first
|
|
operand.
|
|
|
|
Flags Affected
|
|
|
|
CF = 0, OF = 0; SF, ZF, and PF as described in Appendix C; AF is undefined
|
|
|
|
Protected Mode Exceptions
|
|
|
|
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
|
|
memory operand effective address in the CS, DS, ES, FS, or GS segments;
|
|
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page
|
|
fault
|
|
|
|
Real Address Mode Exceptions
|
|
|
|
Interrupt 13 if any part of the operand would lie outside of the effective
|
|
address space from 0 to 0FFFFH
|
|
|
|
Virtual 8086 Mode Exceptions
|
|
|
|
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
|
|
fault
|
|
|
|
|
|
Appendix A Opcode Map
|
|
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
|
|
The opcode tables that follow aid in interpreting 80386 object code. Use
|
|
the high-order four bits of the opcode as an index to a row of the opcode
|
|
table; use the low-order four bits as an index to a column of the table. If
|
|
the opcode is 0FH, refer to the two-byte opcode table and use the second
|
|
byte of the opcode to index the rows and columns of that table.
|
|
|
|
|
|
Key to Abbreviations
|
|
|
|
Operands are identified by a two-character code of the form Zz. The first
|
|
character, an uppercase letter, specifies the addressing method; the second
|
|
character, a lowercase letter, specifies the type of operand.
|
|
|
|
|
|
Codes for Addressing Method
|
|
|
|
A Direct address; the instruction has no modR/M byte; the address of the
|
|
operand is encoded in the instruction; no base register, index register,
|
|
or scaling factor can be applied; e.g., far JMP (EA).
|
|
|
|
C The reg field of the modR/M byte selects a control register; e.g., MOV
|
|
(0F20, 0F22).
|
|
|
|
D The reg field of the modR/M byte selects a debug register; e.g., MOV
|
|
(0F21,0F23).
|
|
|
|
E A modR/M byte follows the opcode and specifies the operand. The operand
|
|
is either a general register or a memory address. If it is a memory
|
|
address, 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.
|
|
|
|
F Flags Register.
|
|
|
|
G The reg field of the modR/M byte selects a general register; e.g., ADD
|
|
(00).
|
|
|
|
I Immediate data. The value of the operand is encoded in subsequent bytes
|
|
of the instruction.
|
|
|
|
J The instruction contains a relative offset to be added to the
|
|
instruction pointer register; e.g., JMP short, LOOP.
|
|
|
|
M The modR/M byte may refer only to memory; e.g., BOUND, LES, LDS, LSS,
|
|
LFS, LGS.
|
|
|
|
O The instruction has no modR/M byte; the offset of the operand is coded as
|
|
a word or double word (depending on address size attribute) in the
|
|
instruction. No base register, index register, or scaling factor can be
|
|
applied; e.g., MOV (A0-A3).
|
|
|
|
R The mod field of the modR/M byte may refer only to a general register;
|
|
e.g., MOV (0F20-0F24, 0F26).
|
|
|
|
S The reg field of the modR/M byte selects a segment register; e.g., MOV
|
|
(8C,8E).
|
|
|
|
T The reg field of the modR/M byte selects a test register; e.g., MOV
|
|
(0F24,0F26).
|
|
|
|
X Memory addressed by DS:SI; e.g., MOVS, COMPS, OUTS, LODS, SCAS.
|
|
|
|
Y Memory addressed by ES:DI; e.g., MOVS, CMPS, INS, STOS.
|
|
|
|
|
|
Codes for Operant Type
|
|
|
|
a Two one-word operands in memory or two double-word operands in memory,
|
|
depending on operand size attribute (used only by BOUND).
|
|
|
|
b Byte (regardless of operand size attribute)
|
|
|
|
c Byte or word, depending on operand size attribute.
|
|
|
|
d Double word (regardless of operand size attribute)
|
|
|
|
p 32-bit or 48-bit pointer, depending on operand size attribute.
|
|
|
|
s Six-byte pseudo-descriptor
|
|
|
|
v Word or double word, depending on operand size attribute.
|
|
|
|
w Word (regardless of operand size attribute)
|
|
|
|
|
|
Register Codes
|
|
|
|
When an operand is a specific register encoded in the opcode, the register
|
|
is identified by its name; e.g., AX, CL, or ESI. The name of the register
|
|
indicates whether the register is 32-, 16-, or 8-bits wide. A register
|
|
identifier of the form eXX is used when the width of the register depends on
|
|
the operand size attribute; for example, eAX indicates that the AX register
|
|
is used when the operand size attribute is 16 and the EAX register is used
|
|
when the operand size attribute is 32.
|
|
|
|
|
|
One-Byte Opcode Map
|
|
|
|
|
|
0 1 2 3 4 5 6 7 8 9 A B C D E F
|
|
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍ»
|
|
º ADD ³ PUSH ³ POP ³ OR ³ PUSH ³ 2-byte º
|
|
0ÇÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄ´ ³ ÃÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄ´ ³ º
|
|
º Eb,Gb ³ Ev,Gv ³ Gb,Eb ³ Gv,Ev ³ AL,Ib ³ eAX,Iv ³ ES ³ ES ³ Eb,Gb ³ Ev,Gv ³ Gb,Eb ³ Gv,Ev ³ AL,Ib ³ eAX,Iv ³ CS ³ escape º
|
|
ÌÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍ͹
|
|
º ADC ³ PUSH ³ POP ³ SBB ³ PUSH ³ POP º
|
|
1ÇÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄ´ ³ ÃÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄ´ ³ º
|
|
º Eb,Gb ³ Ev,Gv ³ Gb,Eb ³ Gv,Ev ³ AL,Ib ³ eAX,Iv ³ SS ³ SS ³ Eb,Gb ³ Ev,Gv ³ Gb,Eb ³ Gv,Ev ³ AL,Ib ³ eAX,Iv ³ DS ³ DS º
|
|
ÌÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍ͹
|
|
º AND ³ SEG ³ ³ SUB ³ SEG ³ º
|
|
2ÇÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄ´ ³ DAA ÃÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄ´ ³ DAS º
|
|
º Eb,Gb ³ Ev,Gv ³ Gb,Eb ³ Gv,Ev ³ AL,Ib ³ eAX,Iv ³ =ES ³ ³ Eb,Gb ³ Ev,Gv ³ Gb,Eb ³ Gv,Ev ³ AL,Ib ³ eAX,Iv ³ =CS ³ º
|
|
ÌÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍ͹
|
|
º XOR ³ SEG ³ ³ CMP ³ SEG ³ º
|
|
3ÇÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄ´ ³ AAA ÃÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄ´ ³ AAS º
|
|
º Eb,Gb ³ Ev,Gv ³ Gb,Eb ³ Gv,Ev ³ AL,Ib ³ eAX,Iv ³ =SS ³ ³ Eb,Gb ³ Ev,Gv ³ Gb,Eb ³ Gv,Ev ³ AL,Ib ³ eAX,Iv ³ =CS ³ º
|
|
ÌÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍ͹
|
|
º INC general register ³ DEC general register º
|
|
4ÇÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄĶ
|
|
º eAX ³ eCX ³ eDX ³ eBX ³ eSP ³ eBP ³ eSI ³ eDI ³ eAX ³ eCX ³ eDX ³ eBX ³ eSP ³ eBP ³ eSI ³ eDI º
|
|
ÌÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍ͹
|
|
º PUSH general register ³ POP into general register º
|
|
5ÇÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄĶ
|
|
º eAX ³ eCX ³ eDX ³ eBX ³ eSP ³ eBP ³ eSI ³ eDI ³ eAX ³ eCX ³ eDX ³ eBX ³ eSP ³ eBP ³ eSI ³ eDI º
|
|
ÌÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍ͹
|
|
º ³ ³ BOUND ³ ARPL ³ SEG ³ SEG ³ Operand³ Address³ PUSH ³ IMUL ³ PUSH ³ IMUL ³ INSB ³ INSW/D ³ OUTSB ³OUTSW/D º
|
|
6º PUSHA ³ POPA ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
º ³ ³ Gv,Ma ³ Ew,Rw ³ =FS ³ =GS ³ Size ³ Size ³ Ib ³ GvEvIv ³ Ib ³ GvEvIv ³ Yb,DX ³ Yb,DX ³ Dx,Xb ³ DX,Xv º
|
|
ÌÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍ͹
|
|
º Short displacement jump of condition (Jb) ³ Short-displacement jump on condition(Jb) º
|
|
7ÇÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄĶ
|
|
º JO ³ JNO ³ JB ³ JNB ³ JZ ³ JNZ ³ JBE ³ JNBE ³ JS ³ JNS ³ JP ³ JNP ³ JL ³ JNL ³ JLE ³ JNLE º
|
|
ÌÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍ͹
|
|
º Immediate Grpl ³ ³ Grpl ³ TEST ³ XCNG ³ MOV ³ MOV ³ LEA ³ MOV ³ POP º
|
|
8ÇÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄ´ ³ ÃÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄ´ ³ ³ ³ º
|
|
º Eb,Ib ³ Ev,Iv ³ ³ Ev,Iv ³ Eb,Gb ³ Ev,Gv ³ Eb,Gb ³ Ev,Gv ³ Eb,Gb ³ Ev,Gv ³ Gb,Eb ³ Gv,Ev ³ Ew,Sw ³ Gv,M ³ Sw,Ew ³ Ev º
|
|
ÌÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍ͹
|
|
º ³ XCHG word or double-word register with eAX ³ ³ ³ CALL ³ ³ PUSHF ³ POPF ³ ³ º
|
|
9º NOP ÃÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄ´ CBW ³ CWD ³ ³ WAIT ³ ³ ³ SAHF ³ LAHF º
|
|
º ³ eCX ³ eDX ³ eBX ³ eSP ³ eBP ³ eSI ³ eDI ³ ³ ³ Ap ³ ³ Fv ³ Fv ³ ³ º
|
|
ÌÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍ͹
|
|
º MOV ³ MOVSB ³ MOVSW/D ³ CMPSB ³CMPSW/D ³ TEST ³ STOSB ³ STOSW/D ³ LODSB ³ LODSW/D ³ SCASB ³SCASW/D º
|
|
AÇÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄ´ ³ ³ ³ ÃÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄ´ ³ ³ ³ ³ ³ º
|
|
º AL,Ob ³ eAX,Ov ³ Ob,AL ³ Ov,eAX ³ Xb,Yb ³ Xv,Yv ³ Xb,Yb ³ Xv,Yv ³ AL,Ib ³ eAX,Iv ³ Yb,AL ³ Yv,eAX ³ AL,Xb ³ eAX,Xv ³ AL,Xb ³eAX,Xv º
|
|
ÌÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍ͹
|
|
º MOV immediate byte into byte register ³ MOV immediate word or double into word or double register º
|
|
BÇÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄĶ
|
|
º AL ³ CL ³ DL ³ BL ³ AH ³ CH ³ DH ³ BH ³ eAX ³ eCX ³ eDX ³ eBX ³ eSP ³ eBP ³ eSI ³ eDI º
|
|
ÌÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍ͹
|
|
º Shift Grp2 ³ RET near ³ LES ³ LDS ³ MOV ³ ENTER ³ ³ RET far ³ INT ³ INT ³ ³ º
|
|
CÇÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄ´ ³ ÃÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄ´ ³ LEAVE ÃÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄ´ ³ ³ INTO ³ IRET º
|
|
º Eb,Ib ³ Ev,Iv ³ Iw ³ ³ Gv,Mp ³ Gv,Mp ³ Eb,Ib ³ Ev,Iv ³ Iw,Ib ³ ³ Iw ³ ³ 3 ³ Ib ³ ³ º
|
|
ÌÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍ͹
|
|
º Shift Grp2 ³ ³ ³ ³ ³ º
|
|
DÇÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄ´ AAM ³ AAD ³ ³ XLAT ³ ESC(Escape to coprocessor instruction set) º
|
|
º Eb,1 ³ Ev,1 ³ Eb,CL ³ Ev,CL ³ ³ ³ ³ ³ º
|
|
ÌÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
|
º LOOPNE ³ LOOPE ³ LOOP ³ JCXZ ³ IN ³ OUT ³ CALL ³ JNP ³ IN ³ OUT º
|
|
Eº ³ ³ ³ ÃÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄ´ ÃÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄĶ
|
|
º Jb ³ Jb ³ Jb ³ Jb ³ AL,Ib ³ eAX,Ib ³ Ib,AL ³ Ib,eAX ³ Av ³ Jv ³ Ap ³ Jb ³ AL,DX ³ eAX,DX ³ DX,AL ³ DX,eAX º
|
|
ÌÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍ͹
|
|
º ³ ³ ³ REP ³ ³ ³ Unary Grp3 ³ ³ ³ ³ ³ ³ ³INC/DEC ³Indirct º
|
|
Fº LOCK ³ ³ REPNE ³ ³ HLT ³ CMC ÃÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄ´ CLC ³ STC ³ CLI ³ STI ³ CLD ³ STD ³ ³ º
|
|
º ³ ³ ³ REPE ³ ³ ³ Eb ³ Ev ³ ³ ³ ³ ³ ³ ³ Grp4 ³ Grp5 º
|
|
ÈÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍͼ
|
|
|
|
|
|
Two-Byte Opcode Map (first byte is 0FH)
|
|
|
|
|
|
0 1 2 3 4 5 6 7 8 9 A B C D E F
|
|
ÉÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍ»
|
|
º ³ ³ LAR ³ LSL ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
0º Grp6 ³ Grp7 ³ ³ ³ ³ ³ CLTS ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
º ³ ³ Gw,Ew ³ Gv,Ew ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
ÌÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍ͹
|
|
º ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
1º ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
º ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
ÌÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍ͹
|
|
º MOV ³ MOV ³ MOV ³ MOV ³ MOV ³ ³ MOV ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
2º ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
º Cd,Rd ³ Dd,Rd ³ Rd,Cd ³ Rd,Dd ³ Td,Rd ³ ³ Rd,Td ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
ÌÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍ͹
|
|
º ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
3º ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
º ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
ÌÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍ͹
|
|
º ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
4º ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
º ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
ÌÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍ͹
|
|
º ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
5º ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
º ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
ÌÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍ͹
|
|
º ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
6º ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
º ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
ÌÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍ͹
|
|
º ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
7º ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
º ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
ÌÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍ͹
|
|
º Long-displacement jump on condition (Jv) ³ Long-displacement jump on condition (Jv) º
|
|
8ÇÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄĶ
|
|
º JO ³ JNO ³ JB ³ JNB ³ JZ ³ JNZ ³ JBE ³ JNBE ³ JS ³ JNS ³ JP ³ JNP ³ JL ³ JNL ³ JLE ³ JNLE º
|
|
ÌÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍ͹
|
|
º Byte Set on condition (Eb) ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
9ÇÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄ´ SETS ³ SETNS ³ SETP ³ SETNP ³ SETL ³ SETNL ³ SETLE ³ SETNLE º
|
|
º SETO ³ SETNO ³ SETB ³ SETNB ³ SETZ ³ SETNZ ³ SETBE ³ SETNBE ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
ÌÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍ͹
|
|
º PUSH ³ POP ³ ³ BT ³ SHLD ³ SHLD ³ ³ ³ PUSH ³ POP ³ ³ BTS ³ SHRD ³ SHRD ³ ³ IMUL º
|
|
Aº ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
º FS ³ FS ³ ³ Ev,Gv ³ EvGvIb ³ EvGvCL ³ ³ ³ GS ³ GS ³ ³ Ev,Gv ³ EvGvIb ³ EvGvCL ³ ³ Gv,Ev º
|
|
ÌÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍ͹
|
|
º ³ ³ LSS ³ BTR ³ LFS ³ LGS ³ MOVZX ³ ³ ³ Grp-8 ³ BTC ³ BSF ³ BSR ³ MOVSX º
|
|
Bº ³ ³ ³ ³ ³ ÃÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄ´ ³ ³ ³ ³ ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
|
º ³ ³ Mp ³ Ev,Gv ³ Mp ³ Mp ³ Gv,Eb ³ Gv,Ew ³ ³ ³ Ev,Ib ³ Ev,Gv ³ Gv,Ev ³ Gv,Ev ³ Gv,Eb Gv,Ew º
|
|
ÌÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍ͹
|
|
º ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
Cº ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
º ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
ÌÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍ͹
|
|
º ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
Dº ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
º ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
ÌÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍ͹
|
|
º ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
Eº ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
º ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
ÌÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍ͹
|
|
º ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
Fº ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
º ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
|
|
ÈÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍͼ
|
|
|
|
|
|
Opcodes determined by bits 5,4,3 of modR/M byte:
|
|
|
|
G ÚÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄ¿
|
|
r ³ mod ³ nnn ³ R/M ³
|
|
o ÀÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÙ
|
|
u
|
|
p 000 001 010 011 100 101 110 111
|
|
ÚÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄ¿
|
|
1³ ADD ³ OR ³ ADC ³ SBB ³ AND ³ SUB ³ XOR ³ CMP ³
|
|
³ ³ ³ ³ ³ ³ ³ ³ ³
|
|
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄ´
|
|
2³ ROL ³ ROR ³ RCL ³ RCR ³ SHL ³ SHR ³ ³ SAR ³
|
|
³ ³ ³ ³ ³ ³ ³ ³ ³
|
|
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄ´
|
|
3³ TEST ³ ³ NOT ³ NEG ³ MUL ³ IMUL ³ DIV ³ IDIV ³
|
|
³ Ib/Iv ³ ³ ³ ³AL/eAX ³AL/eAX ³AL/eAX ³AL/eAX ³
|
|
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄ´
|
|
4³ INC ³ DEC ³ ³ ³ ³ ³ ³ ³
|
|
³ Eb ³ Eb ³ ³ ³ ³ ³ ³ ³
|
|
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄ´
|
|
5³ INC ³ DEC ³ CALL ³ CALL ³ JMP ³ JMP ³ PUSH ³ ³
|
|
³ Ev ³ Ev ³ Ev ³ eP ³ Ev ³ Ep ³ Ev ³ ³
|
|
ÀÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÙ
|
|
|
|
|
|
Opcodes determined by bits 5,4,3 of modR/M byte:
|
|
|
|
G ÚÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄ¿
|
|
r ³ mod ³ nnn ³ R/M ³
|
|
o ÀÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÙ
|
|
u
|
|
p 000 001 010 011 100 101 110 111
|
|
ÚÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄ¿
|
|
6³ SLDT ³ STR ³ LLDT ³ LTR ³ VERR ³ VERW ³ ³ ³
|
|
³ Ew ³ Ew ³ Ew ³ Ew ³ Ew ³ Ew ³ ³ ³
|
|
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄ´
|
|
7³ SGDT ³ SIDT ³ LGDT ³ LIDT ³ SMSW ³ ³ LMSW ³ ³
|
|
³ Ms ³ Ms ³ Ms ³ Ms ³ Ew ³ ³ Ew ³ ³
|
|
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄ´
|
|
8³ ³ ³ ³ ³ BT ³ BTS ³ BTR ³ BTC ³
|
|
³ ³ ³ ³ ³ ³ ³ ³ ³
|
|
ÀÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÙ
|
|
|
|
|
|
Appendix B Complete Flag Cross-Reference
|
|
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
|
|
Key to Codes
|
|
|
|
T = instruction tests flag
|
|
|
|
M = instruction modifies flag
|
|
(either sets or resets depending on operands)
|
|
|
|
0 = instruction resets flag
|
|
|
|
1 = instruction sets flag
|
|
|
|
ÄÄ = instruction's effect on flag is undefined
|
|
|
|
R = instruction restores prior value of flag
|
|
|
|
blank = instruction does not affect flag
|
|
|
|
|
|
Instruction OF SF ZF AF PF CF TF IF DF NT RF
|
|
|
|
AAA ÄÄ ÄÄ ÄÄ TM ÄÄ M
|
|
AAD ÄÄ M M ÄÄ M ÄÄ
|
|
AAM ÄÄ M M ÄÄ M ÄÄ
|
|
AAS ÄÄ ÄÄ ÄÄ TM ÄÄ M
|
|
ADC M M M M M TM
|
|
ADD M M M M M M
|
|
AND 0 M M ÄÄ M 0
|
|
ARPL M
|
|
BOUND
|
|
BSF/BSR ÄÄ ÄÄ M ÄÄ ÄÄ ÄÄ
|
|
BT/BTS/BTR/BTC ÄÄ ÄÄ ÄÄ ÄÄ ÄÄ M
|
|
CALL
|
|
CBW
|
|
CLC 0
|
|
CLD 0
|
|
CLI 0
|
|
CLTS
|
|
CMC M
|
|
CMP M M M M M M
|
|
CMPS M M M M M M T
|
|
CWD
|
|
DAA ÄÄ M M TM M TM
|
|
DAS ÄÄ M M TM M TM
|
|
DEC M M M M M
|
|
DIV ÄÄ ÄÄ ÄÄ ÄÄ ÄÄ ÄÄ
|
|
ENTER
|
|
ESC
|
|
HLT
|
|
IDIV ÄÄ ÄÄ ÄÄ ÄÄ ÄÄ ÄÄ
|
|
IMUL M ÄÄ ÄÄ ÄÄ ÄÄ M
|
|
IN
|
|
INC M M M M M
|
|
INS T
|
|
INT 0 0
|
|
INTO T 0 0
|
|
IRET R R R R R R R R R T
|
|
Jcond T T T T T
|
|
JCXZ
|
|
JMP
|
|
LAHF
|
|
LAR M
|
|
LDS/LES/LSS/LFS/LGS
|
|
LEA
|
|
LEAVE
|
|
LGDT/LIDT/LLDT/LMSW
|
|
LOCK
|
|
LODS T
|
|
LOOP
|
|
LOOPE/LOOPNE T
|
|
LSL M
|
|
LTR
|
|
MOV
|
|
MOV control, debug ÄÄ ÄÄ ÄÄ ÄÄ ÄÄ ÄÄ
|
|
MOVS T
|
|
MOVSX/MOVZX
|
|
MUL M ÄÄ ÄÄ ÄÄ ÄÄ M
|
|
NEG M M M M M M
|
|
NOP
|
|
NOT
|
|
OR 0 M M ÄÄ M 0
|
|
OUT
|
|
OUTS T
|
|
POP/POPA
|
|
POPF R R R R R R R R R R
|
|
PUSH/PUSHA/PUSHF
|
|
RCL/RCR 1 M TM
|
|
RCL/RCR count ÄÄ TM
|
|
REP/REPE/REPNE
|
|
RET
|
|
ROL/ROR 1 M M
|
|
ROL/ROR count ÄÄ M
|
|
SAHF R R R R R
|
|
SAL/SAR/SHL/SHR 1 M M M ÄÄ M M
|
|
SAL/SAR/SHL/SHR count ÄÄ M M ÄÄ M M
|
|
SBB M M M M M TM
|
|
SCAS M M M M M M T
|
|
SET cond T T T T T
|
|
SGDT/SIDT/SLDT/SMSW
|
|
SHLD/SHRD ÄÄ M M ÄÄ M M
|
|
STC 1
|
|
STD 1
|
|
STI 1
|
|
STOS T
|
|
STR
|
|
SUB M M M M M M
|
|
TEST 0 M M ÄÄ M 0
|
|
VERR/VERRW M
|
|
WAIT
|
|
XCHG
|
|
XLAT
|
|
XOR 0 M M ÄÄ M 0
|
|
|
|
|
|
Appendix C Status Flag Summary
|
|
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
|
|
Status Flags' Functions
|
|
|
|
Bit Name Function
|
|
|
|
0 CF Carry Flag ÄÄ Set on high-order bit carry or borrow; cleared
|
|
otherwise.
|
|
2 PF Parity Flag ÄÄ Set if low-order eight bits of result contain
|
|
an even number of 1 bits; cleared otherwise.
|
|
4 AF Adjust flag ÄÄ Set on carry from or borrow to the low order
|
|
four bits of AL; cleared otherwise. Used for decimal
|
|
arithmetic.
|
|
6 ZF Zero Flag ÄÄ Set if result is zero; cleared otherwise.
|
|
7 SF Sign Flag ÄÄ Set equal to high-order bit of result (0 is
|
|
positive, 1 if negative).
|
|
11 OF Overflow Flag ÄÄ Set if result is too large a positive number
|
|
or too small a negative number (excluding sign-bit) to fit in
|
|
destination operand; cleared otherwise.
|
|
|
|
Key to Codes
|
|
|
|
T = instruction tests flag
|
|
M = instruction modifies flag
|
|
(either sets or resets depending on operands)
|
|
0 = instruction resets flag
|
|
ÄÄ = instruction's effect on flag is undefined
|
|
blank = instruction does not affect flag
|
|
|
|
|
|
|
|
Instruction OF SF ZF AF PF CF
|
|
AAA ÄÄ ÄÄ ÄÄ TM ÄÄ M
|
|
AAS ÄÄ ÄÄ ÄÄ TM ÄÄ M
|
|
AAD ÄÄ M M ÄÄ M ÄÄ
|
|
AAM ÄÄ M M ÄÄ M ÄÄ
|
|
DAA ÄÄ M M TM M TM
|
|
DAS ÄÄ M M TM M TM
|
|
ADC M M M M M TM
|
|
ADD M M M M M M
|
|
SBB M M M M M TM
|
|
SUB M M M M M M
|
|
CMP M M M M M M
|
|
CMPS M M M M M M
|
|
SCAS M M M M M M
|
|
NEG M M M M M M
|
|
DEC M M M M M
|
|
INC M M M M M
|
|
IMUL M ÄÄ ÄÄ ÄÄ ÄÄ M
|
|
MUL M ÄÄ ÄÄ ÄÄ ÄÄ M
|
|
RCL/RCR 1 M TM
|
|
RCL/RCR count ÄÄ TM
|
|
ROL/ROR 1 M M
|
|
ROL/ROR count ÄÄ M
|
|
SAL/SAR/SHL/SHR 1 M M M ÄÄ M M
|
|
SAL/SAR/SHL/SHR count ÄÄ M M ÄÄ M M
|
|
SHLD/SHRD ÄÄ M M ÄÄ M M
|
|
BSF/BSR ÄÄ ÄÄ M ÄÄ ÄÄ ÄÄ
|
|
BT/BTS/BTR/BTC ÄÄ ÄÄ ÄÄ ÄÄ ÄÄ M
|
|
AND 0 M M ÄÄ M 0
|
|
OR 0 M M ÄÄ M 0
|
|
TEST 0 M M ÄÄ M 0
|
|
XOR 0 M M ÄÄ M 0
|
|
|
|
|
|
Appendix D Condition Codes
|
|
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
Note:
|
|
The terms "above" and "below" refer to the relation between two
|
|
unsigned values (neither SF nor OF is tested). The terms "greater" and
|
|
"less" refer to the relation between two signed values (SF and OF are
|
|
tested).
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
|
|
Definition of Conditions
|
|
|
|
(For conditional instructions Jcond, and SETcond)
|
|
|
|
|
|
Instruction Condition
|
|
Mnemonic Meaning Subcode Tested
|
|
|
|
O Overflow 0000 OF = 1
|
|
|
|
NO No overflow 0001 OF = 0
|
|
|
|
B Below
|
|
NAE Neither above nor equal 0010 CF = 1
|
|
|
|
NB Not below
|
|
AE Above or equal 0011 CF = 0
|
|
|
|
E Equal
|
|
Z Zero 0100 ZF = 1
|
|
|
|
NE Not equal
|
|
NZ Not zero 0101 ZF = 0
|
|
|
|
BE Below or equal
|
|
NA Not above 0110 (CF or ZF) = 1
|
|
|
|
NBE Neither below nor equal
|
|
NA Above 0111 (CF or ZF) = 0
|
|
|
|
S Sign 1000 SF = 1
|
|
|
|
NS No sign 1001 SF = 0
|
|
|
|
P Parity
|
|
PE Parity even 1010 PF = 1
|
|
|
|
NP No parity
|
|
PO Parity odd 1011 PF = 0
|
|
|
|
L Less
|
|
NGE Neither greater nor equal 1100 (SF xor OF) = 1
|
|
|
|
NL Not less
|
|
GE Greater or equal 1101 (SF xor OF) = 0
|
|
|
|
LE Less or equal
|
|
NG Not greater 1110 ((SF xor OF) or ZF) = 1
|
|
|
|
NLE Neither less nor equal
|
|
G Greater 1111 ((SF xor OF) or ZF) = 0
|