Am186 and Am188 Family Instruction Set Manual February, 1997 © 1997 Advanced Micro Devices, Inc. Advanced Micro Devices reserves the right to make changes in its products without notice in order to improve design or performance characteristics. This publication neither states nor implies any warranty of any kind, including but not limited to implied warrants of merchantability or fitness for a particular application. AMD assumes no responsibility for the use of any circuitry other than the circuitry in an AMD product. The information in this publication is believed to be accurate in all respects at the time of publication, but is subject to change without notice. AMD assumes no responsibility for any errors or omissions, and disclaims responsibility for any consequences resulting from the use of the information included herein. Additionally, AMD assumes no responsibility for the functioning of undescribed features or parameters. Trademarks AMD, the AMD logo, and combinations thereof are trademarks of Advanced Micro Devices, Inc. Am186, Am188, and E86 are trademarks of Advanced Micro Devices, Inc. FusionE86 is a service mark of Advanced Micro Devices, Inc. Product names used in this publication are for identification purposes only and may be trademarks of their respective companies. PREFACE INTRODUCTION AND OVERVIEW AMD has a strong history in x86 architecture and its E86™ family meets customer requirements of low system cost, high performance, quality vendor reputation, quick time to market, and an easy upgrade strategy. The 16-bit Am186™ and Am188™ family of microcontrollers is based on the architecture of the original 8086 and 8088 microcontrollers, and currently includes the 80C186, 80C188, 80L186, 80L188, Am186EM, Am186EMLV, Am186ER, Am186ES, Am186ESLV, Am188EM, Am188EMLV, Am188ER, Am188ES, and Am188ESLV. Throughout this manual, the term Am186 and Am188 microcontrollers refers to any of these microcontrollers as well as future members based on the same core. The Am186EM/ER/ES and Am188EM/ES/ER microcontrollers build on the 80C186/ 80C188 microcontroller cores and offer 386-class performance while lowering system cost. Designers can reduce the cost, size, and power consumption of embedded systems, while increasing performance and functionality. This is achieved by integrating key system peripherals onto the microcontroller. These low-cost, high-performance microcontrollers for embedded systems provide a natural migration path for 80C186/80C188 designs that need performance and cost enhancements. PURPOSE OF THIS MANUAL Each member of the Am186 and Am188 family of microcontrollers shares the standard 186 instruction set. This manual describes that instruction set. Details on technical features of family members can be found in the user’s manual for that specific device. Additional information is available in the form of data sheets, application notes, and other documentation provided with software products and hardware-development tools. INTENDED AUDIENCE This manual is intended for computer hardware and software engineers and system architects who are designing or are considering designing systems based on the Am186 and Am188 family of microcontrollers. MANUAL OVERVIEW The information in this manual is organized into 4 chapters and 1 appendix. n Chapter 1 provides a programming overview of the Am186 and Am188 microcontrollers, including the register set, instruction set, memory organization and address generation, I/O space, segments, data types, and addressing modes. n Chapter 2 offers an instruction set overview, detailing the format of the instructions. n Chapter 3 contains an instruction set listing, both by functional type and in alphabetical order. n Chapter 4 describes in detail each instruction in the Am186 and Am188 microcontrollers instruction set. n Appendix A provides an instruction set summary table, as well as a guide to the instruction set by hex and binary opcode. Introduction and Overview iii AMD DOCUMENTATION E86 Family ORDER NO. DOCUMENT TITLE 19168 Am186EM and Am188EM Microcontrollers Data Sheet Hardware documentation for the Am186EM, Am186EMLV, Am188EM, and Am188EMLV microcontrollers: pin descriptions, functional descriptions, absolute maximum ratings, operating ranges, switching characteristics and waveforms, connection diagrams and pinouts, and package physical dimensions. 20732 Am186ER and Am188ER Microcontrollers Data Sheet Hardware documentation for the Am186ER and Am188ER microcontrollers: pin descriptions, functional descriptions, absolute maximum ratings, operating ranges, switching characteristics and waveforms, connection diagrams and pinouts, and package physical dimensions. 20002 Am186ES and Am188ES Microcontrollers Data Sheet Hardware documentation for the Am186ES, Am186ESLV, Am188ES, and Am188ESLV microcontrollers: pin descriptions, functional descriptions, absolute maximum ratings, operating ranges, switching characteristics and waveforms, connection diagrams and pinouts, and package physical dimensions. 20071 E86 Family Support Tools Brief Lists available E86 family software and hardware development tools, as well as contact information for suppliers. 19255 FusionE86SM Catalog Provides information on tools that speed an E86 family embedded product to market. Includes products from expert suppliers of embedded development solutions. 21058 FusionE86 Development Tools Reference CD Provides a single-source multimedia tool for customer evaluation of AMD products as well as Fusion partner tools and technologies that support the E86 family of microcontrollers and microprocessors. Technical documentation for the E86 family is included on the CD in PDF format. To order literature, contact the nearest AMD sales office or call 800-222-9323 (in the U.S. and Canada) or direct dial from any location 512-602-5651. Literature is also available in postscript and PDF formats on the AMD web site. To access the AMD home page, go to http:/ /www.amd.com. iv Introduction and Overview TABLE OF CONTENTS PREFACE INTRODUCTION AND OVERVIEW III PURPOSE OF THIS MANUAL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . III INTENDED AUDIENCE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . III MANUAL OVERVIEW . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . III AMD DOCUMENTATIONiv E86 Family . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iv CHAPTER 1 PROGRAMMING 1.1 REGISTER SET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-1 1.1.1 Processor Status Flags Register . . . . . . . . . . . . . . . . . . . . . . . . . 1-2 1.2 INSTRUCTION SET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-3 1.3 MEMORY ORGANIZATION AND ADDRESS GENERATION . . . . . . . . . . 1-3 1.4 I/O SPACE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-5 1.5 SEGMENTS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-5 1.6 DATA TYPES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-5 1.7 ADDRESSING MODES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-7 Register and Immediate Operands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-7 Memory Operands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-7 CHAPTER 2 INSTRUCTION SET OVERVIEW 2.1 OVERVIEW . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-1 2.2 INSTRUCTION FORMAT. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-1 2.2.1 Instruction Prefixes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-1 2.2.2 Segment Override Prefix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-2 2.2.3 Opcode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-2 2.2.4 Operand Address . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-2 2.2.5 Displacement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-3 2.2.6 Immediate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-3 2.3 NOTATION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-3 2.4 USING THIS manual . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-4 2.4.1 Mnemonics and Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-4 2.4.2 Forms of the Instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-4 2.4.3 What It Does . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-6 2.4.4 Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-6 2.4.5 Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-6 2.4.6 Operation It Performs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-7 2.4.7 Flag Settings After Instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-7 2.4.8 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-7 2.4.9 Tips . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-8 2.4.10 Related Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-8 CHAPTER 3 INSTRUCTION SET LISTING 3.1 INSTRUCTION SET BY TYPE. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-1 3.1.1 Address Calculation and Translation . . . . . . . . . . . . . . . . . . . . . . 3-1 3.1.2 Binary Arithmetic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-2 Table of Contents v 3.1.4 Comparison . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-3 3.1.5 Control Transfer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-3 3.1.6 Data Movement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-5 3.1.7 Decimal Arithmetic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-6 3.1.8 Flag . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-7 3.1.9 Input/Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-8 3.1.10 Logical Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-8 3.1.11 Processor Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-9 3.1.12 String . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-9 3.2 INSTRUCTION SET in alphabetical order . . . . . . . . . . . . . . . . . . . . . . . . 3-11 CHAPTER 4 vi INSTRUCTION SET 4.1 INSTRUCTIONS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-1 AAA ASCII Adjust AL After Addition..................................................... 4-2 AAD ASCII Adjust AX Before Division.................................................. 4-4 AAM ASCII Adjust AL After Multiplication ............................................. 4-6 AAS ASCII Adjust AL After Subtraction................................................ 4-8 ADC Add Numbers with Carry ............................................................ 4-10 ADD Add Numbers ............................................................................ 4-14 AND Logical AND ............................................................................... 4-17 BOUND Check Array Index Against Bounds ........................................... 4-19 CALL Call Procedure ........................................................................... 4-21 CBW Convert Byte Integer to Word..................................................... 4-24 CLC Clear Carry Flag......................................................................... 4-26 CLD Clear Direction Flag ................................................................... 4-29 CLI Clear Interrupt-Enable Flag........................................................ 4-31 CMC Complement Carry Flag ............................................................. 4-33 CMP Compare Components ............................................................... 4-34 CMPS Compare String Components..................................................... 4-36 CWD Convert Word Integer to Doubleword......................................... 4-40 DAA Decimal Adjust AL After Addition ............................................... 4-42 DAS Decimal Adjust AL After Subtraction .......................................... 4-45 DEC Decrement Number by One ....................................................... 4-48 DIV Divide Unsigned Numbers ......................................................... 4-50 ENTER Enter High-Level Procedure....................................................... 4-53 ESC Escape ....................................................................................... 4-56 HLT Halt............................................................................................. 4-57 IDIV Divide Integers ........................................................................... 4-60 IMUL Multiply Integers ......................................................................... 4-63 IN Input Component from Port........................................................ 4-67 INC Increment Number by One......................................................... 4-69 INS Input String Component from Port ............................................. 4-71 INT Generate Interrupt...................................................................... 4-73 IRET Interrupt Return .......................................................................... 4-76 JA Jump If Above ............................................................................ 4-78 JAE Jump If Above or Equal.............................................................. 4-80 JB Jump If Below............................................................................. 4-82 JBE Jump If Below or Equal .............................................................. 4-84 JC Jump If Carry.............................................................................. 4-86 JCXZ Jump If CX Register Is Zero....................................................... 4-87 JE Jump If Equal ............................................................................. 4-89 Table of Contents JG JGE JL JLE JMP JNA JNAE JNB JNBE JNC JNE JNG JNGE JNL JNLE JNO JNP JNS JNZ JO JP JPE JPO JS JZ LAHF LDS LEA LEAVE LES LOCK LODS LOOP LOOPE LOOPNE LOOPZ MOV MOVS MUL NEG NOP NOT OR OUT OUTS POP POPA POPF PUSH Jump If Greater .......................................................................... 4-91 Jump If Greater or Equal............................................................ 4-93 Jump If Less............................................................................... 4-95 Jump If Less or Equal ................................................................ 4-97 Jump Unconditionally ................................................................. 4-99 Jump If Not Above.................................................................... 4-102 Jump If Not Above or Equal ..................................................... 4-103 Jump If Not Below .................................................................... 4-104 Jump If Not Below or Equal...................................................... 4-105 Jump If Not Carry ..................................................................... 4-106 Jump If Not Equal..................................................................... 4-107 Jump If Not Greater.................................................................. 4-109 Jump If Not Greater or Equal ................................................... 4-110 Jump If Not Less ...................................................................... 4-111 Jump If Not Less or Equal........................................................ 4-112 Jump If Not Overflow................................................................ 4-113 Jump If Not Parity..................................................................... 4-115 Jump If Not Sign....................................................................... 4-116 Jump If Not Zero ...................................................................... 4-118 Jump If Overflow ...................................................................... 4-119 Jump If Parity ........................................................................... 4-121 Jump If Parity Even .................................................................. 4-122 Jump If Parity Odd ................................................................... 4-124 Jump If Sign ............................................................................. 4-126 Jump If Zero ............................................................................. 4-128 Load AH with Flags .................................................................. 4-129 Load DS with Segment and Register with Offset ..................... 4-131 Load Effective Address ........................................................... 4-133 Leave High-Level Procedure.................................................... 4-135 Load ES with Segment and Register with Offset .......................... 4-138 Lock the Bus ............................................................................ 4-140 Load String Component ........................................................... 4-141 Loop While CX Register Is Not Zero ........................................ 4-146 Loop If Equal ............................................................................ 4-148 Loop If Not Equal ..................................................................... 4-150 Loop If Zero.............................................................................. 4-152 Move Component..................................................................... 4-153 Move String Component .......................................................... 4-156 Multiply Unsigned Numbers ..................................................... 4-160 Two’s Complement Negation ................................................... 4-163 No Operation............................................................................ 4-165 One’s Complement Negation ................................................... 4-167 Logical Inclusive OR ................................................................ 4-169 Output Component to Port ....................................................... 4-171 Output String Component to Port............................................. 4-173 Pop Component from Stack ..................................................... 4-175 Pop All 16-Bit General Registers from Stack................................ 4-178 Pop Flags from Stack............................................................... 4-180 Push Component onto Stack ................................................... 4-181 Table of Contents vii PUSHA PUSHF RCL RCR REP REPE REPNE REPZ RET ROL ROR SAHF SAL SAR SBB SCAS SHL SHR STC STD STI STOS SUB TEST WAIT XCHG XLAT XOR APPENDIX A Push All 16-Bit General Registers onto Stack.......................... 4-184 Push Flags onto Stack ............................................................. 4-186 Rotate through Carry Left......................................................... 4-187 Rotate through Carry Right ...................................................... 4-189 Repeat...................................................................................... 4-191 Repeat While Equal ................................................................. 4-193 Repeat While Not Equal........................................................... 4-197 Repeat While Zero ................................................................... 4-201 Return from Procedure............................................................. 4-202 Rotate Left................................................................................ 4-205 Rotate Right ............................................................................. 4-207 Store AH in Flags ..................................................................... 4-209 Shift Arithmetic Left .................................................................. 4-211 Shift Arithmetic Right................................................................ 4-214 Subtract Numbers with Borrow ................................................ 4-216 Scan String for Component...................................................... 4-219 Shift Left ................................................................................... 4-224 Shift Right................................................................................. 4-225 Set Carry Flag .......................................................................... 4-228 Set Direction Flag..................................................................... 4-231 Set Interrupt-Enable Flag ......................................................... 4-235 Store String Component........................................................... 4-237 Subtract Numbers .................................................................... 4-240 Logical Compare ...................................................................... 4-243 Wait for Coprocessor ............................................................... 4-245 Exchange Components............................................................ 4-246 Translate Table Index to Component....................................... 4-248 Logical Exclusive OR ............................................................... 4-251 INSTRUCTION SET SUMMARY INDEX viii Table of Contents LIST OF FIGURES Figure 1-1 Figure 1-2 Figure 1-3 Figure 1-4 Figure 1-5 Figure 2-1 Figure 2-2 Register Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-2 Processor Status Flags Register (FLAGS) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-2 Physical-Address Generation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-4 Memory and i/O Space . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-4 Supported Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-6 Instruction Mnemonic and Name Sample . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-4 Instruction Forms Table Sample . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-4 LIST OF TABLES Table 1-1 Table 1-2 Table 2-1 Table 2-2 Table 2-3 Table 3-4 Segment Register Selection Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-5 Memory Addressing Mode Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-7 mod field . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-2 aux field . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-3 r/m field . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-3 Instruction Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-11 Table of Contents ix x Table of Contents CHAPTER 1 PROGRAMMING All members of the Am186 and Am188 family of microcontrollers contain the same basic set of registers, instructions, and addressing modes, and are compatible with the original industry-standard 186/188 parts. 1.1 REGISTER SET The base architecture for Am186 and Am188 microcontrollers has 14 registers (see Figure 1-1), which are controlled by the instructions detailed in this manual. These registers are grouped into the following categories. n General Registers—Eight 16-bit general purpose registers can be used for arithmetic and logical operands. Four of these (AX, BX, CX, and DX) can be used as 16-bit registers or split into pairs of separate 8-bit registers (AH, AL, BH, BL, CH, CL, DH, and DL). The Destination Index (DI) and Source Index (SI) general-purpose registers are used for data movement and string instructions. The Base Pointer (BP) and Stack Pointer (SP) general-purpose registers are used for the stack segment and point to the bottom and top of the stack, respectively. – Base and Index Registers—Four of the general-purpose registers (BP, BX, DI, and SI) can also be used to determine offset addresses of operands in memory. These registers can contain base addresses or indexes to particular locations within a segment. The addressing mode selects the specific registers for operand and address calculations. – Stack Pointer Register—All stack operations (POP, POPA, POPF, PUSH, PUSHA, PUSHF) utilize the stack pointer. The Stack Pointer (SP) register is always offset from the Stack Segment (SS) register, and no segment override is allowed. n Segment Registers—Four 16-bit special-purpose registers (CS, DS, ES, and SS) select, at any given time, the segments of memory that are immediately addressable for code (CS), data (DS and ES), and stack (SS) memory. n Status and Control Registers—Two 16-bit special-purpose registers record or alter certain aspects of the processor state—the Instruction Pointer (IP) register contains the offset address of the next sequential instruction to be executed and the Processor Status Flags (FLAGS) register contains status and control flag bits (see Figure 1-2). Note that all members of the Am186 and Am188 family of microcontrollers have additional peripheral registers, which are external to the processor. These peripheral registers are not directly accessible by the instruction set. However, because the processor treats these peripheral registers like memory, instructions that have operands that access memory can also access peripheral registers. The above processor registers, as well as the additional peripheral registers, are described in the user’s manual for each specific part. Programming 1-1 Figure 1-1 16-Bit Register Name Byte Addressable (8-Bit Register Names Shown) Register Set 7 0 7 0 AX AH AL DX DH CX 16-Bit Register Name 15 CS DL Multiply/Divide I/O Instructions CH CL Loop/Shift/Repeat/Count SS BX BH BL BP base pointer SI source index DI destination index General Registers Code Segment Data Segment Stack Segment ES Extra Segment Segment Registers Index Registers 15 Stack Pointer 15 0 DS Base Registers SP 1.1.1 Special Register Functions 0 FLAGS Processor Status Flags IP 0 Instruction Pointer Status and Control Registers Processor Status Flags Register The 16-bit processor status flags register (see Figure 1-2) records specific characteristics of the result of logical and arithmetic instructions (bits 0, 2, 4, 6, 7, and 11) and controls the operation of the microcontroller within a given operating mode (bits 8, 9, and 10). After an instruction is executed, the value of a flag may be set (to 1), cleared/reset (to 0), unchanged, or undefined. The term undefined means that the flag value prior to the execution of the instruction is not preserved, and the value of the flag after the instruction is executed cannot be predicted. The documentation for each instruction indicates how each flag bit is affected by that instruction. Figure 1-2 Processor Status Flags Register (FLAGS) 7 15 0 Reserved OF AF DF PF Res Res CF Res IF TF SF ZF Bits 15–12—Reserved. Bit 11: Overflow Flag (OF)—Set if the signed result cannot be expressed within the number of bits in the destination operand, cleared otherwise. 1-2 Programming Bit 10: Direction Flag (DF)—Causes string instructions to auto decrement the appropriate index registers when set. Clearing DF causes auto-increment. See the CLD and STD instructions, respectively, for how to clear and set the Direction Flag. Bit 9: Interrupt-Enable Flag (IF)—When set, enables maskable interrupts to cause the CPU to transfer control to a location specified by an interrupt vector. See the CLI and STI instructions, respectively, for how to clear and set the Interrupt-Enable Flag. Bit 8: Trace Flag (TF)—When set, a trace interrupt occurs after instructions execute. TF is cleared by the trace interrupt after the processor status flags are pushed onto the stack. The trace service routine can continue tracing by popping the flags back with an IRET instruction. Bit 7: Sign Flag (SF)—Set equal to high-order bit of result (set to 0 if 0 or positive, 1 if negative). Bit 6: Zero Flag (ZF)—Set if result is 0; cleared otherwise. Bit 5: Reserved Bit 4: Auxiliary Carry (AF)—Set on carry from or borrow to the low-order 4 bits of the AL general-purpose register; cleared otherwise. Bit 3: Reserved Bit 2: Parity Flag (PF)—Set if low-order 8 bits of result contain an even number of 1 bits; cleared otherwise. Bit 1: Reserved Bit 0: Carry Flag (CF)—Set on high-order bit carry or borrow; cleared otherwise. See the CLC, CMC, and STC instructions, respectively, for how to clear, toggle, and set the Carry Flag. You can use CF to indicate the outcome of a procedure, such as when searching a string for a character. For instance, if the character is found, you can use STC to set CF to 1; if the character is not found, you can use CLC to clear CF to 0. Then, subsequent instructions that do not affect CF can use its value to determine the appropriate course of action. 1.2 INSTRUCTION SET Each member of the Am186 and Am188 family of microcontrollers shares the standard 186 instruction set. An instruction can reference from zero to several operands. An operand can reside in a register, in the instruction itself, or in memory. Specific operand addressing modes are discussed on page 1-7. Chapter 2 provides an overview of the instruction set, describing the format of the instructions. Chapter 3 lists all the instructions for the Am186 and Am188 microcontrollers in both functional and alphabetical order. Chapter 4 details each instruction. 1.3 MEMORY ORGANIZATION AND ADDRESS GENERATION The Am186 and Am188 microcontrollers organize memory in sets of segments. Memory is addressed using a two-component address that consists of a 16-bit segment value and a 16-bit offset. Each segment is a linear contiguous sequence of 64K (216) 8-bit bytes of memory in the processor’s address space. The offset is the number of bytes from the beginning of the segment (the segment address) to the data or instruction which is being accessed. The processor forms the physical address of the target location by taking the segment address, shifting it to the left 4 bits (multiplying by 16), and adding this to the 16-bit offset. Programming 1-3 The result is a 20-bit address of the target data or instruction. This allows for a 1-Mbyte physical address size. For example, if the segment register is loaded with 12A4h and the offset is 0022h, the resultant address is 12A62h (see Figure 1-3). To find the result: 1. The segment register contains 12A4h. 2. The segment register is shifted 4 places and is now 12A40h. 3. The offset is 0022h. 4. The shifted segment address (12A40h) is added to the offset (00022h) to get 12A62h. 5. This address is placed on the address bus pins of the controller. All instructions that address operands in memory must specify (implicitly or explicitly) a 16bit segment value and a 16-bit offset value. The 16-bit segment values are contained in one of four internal segment registers (CS, DS, ES, and SS). See "Addressing Modes” on page 1-7 for more information on calculating the segment and offset values. See "Segments" on page 1-5 for more information on the CS, DS, ES, and SS registers. In addition to memory space, all Am186 and Am188 microcontrollers provide 64K of I/O space (see Figure 1-4). The I/O space is described on page 1-5. Figure 1-3 Physical-Address Generation Shift Left 4 Bits 1 2 A 15 0 0 0 2 15 1 2 A 4 19 4 2 0 0 2 15 1 0 2 2 A 6 2 Physical Address 0 To Memory Memory and i/O Space 1M I/O Space 1-4 Offset 0 0 19 Memory Space Logical Address 0 0 Figure 1-4 Segment Base 64K Programming 1.4 I/O SPACE The I/O space consists of 64K 8-bit or 32K 16-bit ports. The IN and OUT instructions address the I/O space with either an 8-bit port address specified in the instruction, or a 16-bit port address in the DX register. 8-bit port addresses are zero-extended so that A15–A8 are Low. I/O port addresses 00F8h through 00FFh are reserved. The Am186 and Am188 microcontrollers provide specific instructions for addressing I/O space. 1.5 SEGMENTS The Am186 and Am188 microcontrollers use four segment registers: 1. Data Segment (DS): The processor assumes that all accesses to the program’s variables are from the 64K space pointed to by the DS register. The data segment holds data, operands, etc. 2. Code Segment (CS): This 64K space is the default location for all instructions. All code must be executed from the code segment. 3. Stack Segment (SS): The processor uses the SS register to perform operations that involve the stack, such as pushes and pops. The stack segment is used for temporary space. 4. Extra Segment (ES): Usually this segment is used for large string operations and for large data structures. Certain string instructions assume the extra segment as the segment portion of the address. The extra segment is also used (by using segment override) as a spare data segment. When a segment register is not specified for a data movement instruction, it’s assumed to be a data segment. An instruction prefix can be used to override the segment register (see "Segment Override Prefix" on page 2-2).For speed and compact instruction encoding, the segment register used for physical-address generation is implied by the addressing mode used (see Table 1-1). Table 1-1 Segment Register Selection Rules Memory Reference Needed Segment Register Used Implicit Segment Selection Rule Local Data Data (DS) All data references Instructions Code (CS) Instructions (including immediate data) Stack Stack (SS) All stack pushes and pops Any memory references that use the BP register External Data (Global) Extra (ES) All string instruction references that use the DI register as an index 1.6 DATA TYPES The Am186 and Am188 microcontrollers directly support the following data types: n Integer—A signed binary numeric value contained in an 8-bit byte or a 16-bit word. All operations assume a two’s complement representation. n Ordinal—An unsigned binary numeric value contained in an 8-bit byte or a 16-bit word. n Double Word—A signed binary numeric value contained in two sequential 16-bit addresses, or in a DX::AX register pair. n Quad Word—A signed binary numeric value contained in four sequential 16-bit addresses. n BCD—An unpacked byte representation of the decimal digits 0–9. Programming 1-5 n ASCII—A byte representation of alphanumeric and control characters using the ASCII standard of character representation. n Packed BCD—A packed byte representation of two decimal digits (0–9). One digit is stored in each nibble (4 bits) of the byte. n String—A contiguous sequence of bytes or words. A string can contain from 1 byte up to 64 Kbyte. n Pointer—A 16-bit or 32-bit quantity, composed of a 16-bit offset component or a 16-bit segment base component plus a 16-bit offset component. In general, individual data elements must fit within defined segment limits. Figure 1-5 graphically represents the data types supported by the Am186 and Am188 microcontrollers. Figure 1-5 Signed Byte Supported Data Types 7 0 Binary Coded Decimal (BCD) Sign Bit Magnitude Unsigned Byte 7 0 Signed Double Word Sign Bit 0 87 +3 +1 0 1615 1-6 15 +N +N +6 +5 48 47 +4 +3 32 31 +3 +2 +1 16 15 +0 +1 07 0 0 ASCII ASCII Character1 Character0 7 0 +1 0 7 0 0 0 Least Significant Digit 7 +1 0 7 0 0 +2 +1 0 Pointer 0 Segment Base Magnitude Unsigned Word 7 BCD Digit 0 0 String ... Byte/WordN Byte/Word1 Byte/Word0 MSB +1 0 ... 7 0 MSB +7 0 Most Significant Digit +2 31 63 +N Packed BCD MSB Magnitude 0 07 ... 7 0 +1 BCD Digit 1 BCD Digit N Magnitude Signed Quad Word Sign Bit 7 ASCII CharacterN +1 Sign Bit 0 ASCII MSB 1514 +N ... 7 Magnitude Signed Word 7 0 MSB Magnitude Programming Offset 1.7 ADDRESSING MODES The Am186 and Am188 microcontrollers use eight categories of addressing modes to specify operands. Two addressing modes are provided for instructions that operate on register or immediate operands; six modes are provided to specify the location of an operand in a memory segment. Register and Immediate Operands 1. Register Operand Mode—The operand is located in one of the 8- or 16-bit registers. 2. Immediate Operand Mode—The operand is included in the instruction. Memory Operands A memory-operand address consists of two 16-bit components: a segment value and an offset. The segment value is supplied by a 16-bit segment register either implicitly chosen by the addressing mode (described below) or explicitly chosen by a segment override prefix (see "Segment Override Prefix" on page 2-2). The offset, also called the effective address, is calculated by summing any combination of the following three address elements: n Displacement—an 8-bit or 16-bit immediate value contained in the instruction n Base—contents of either the BX or BP base registers n Index—contents of either the SI or DI index registers Any carry from the 16-bit addition is ignored. Eight-bit displacements are sign-extended to 16-bit values. Combinations of the above three address elements define the following six memory addressing modes (see Table 1-2 for examples). 1. Direct Mode—The operand offset is contained in the instruction as an 8- or 16-bit displacement element. 2. Register Indirect Mode—The operand offset is in one of the BP, BX, DI, or SI registers. 3. Based Mode—The operand offset is the sum of an 8- or 16-bit displacement and the contents of a base register (BP or BX). 4. Indexed Mode—The operand offset is the sum of an 8- or 16-bit displacement and the contents of an index register (DI or SI). 5. Based Indexed Mode—The operand offset is the sum of the contents of a base register (BP or BX) and an index register (DI or SI). 6. Based Indexed Mode with Displacement—The operand offset is the sum of a base register’s contents, an index register’s contents, and an 8-bit or 16-bit displacement. Table 1-2 Memory Addressing Mode Examples Addressing Mode Example Direct Register Indirect Based Indexed Based Indexed Based Indexed with Displacement mov mov mov mov mov mov Programming ax, ax, ax, ax, ax, ax, ds:4 [si] [bx]4 [si]4 [si][bx] [si][bx]4 1-7 1-8 Programming CHAPTER 2 2.1 INSTRUCTION SET OVERVIEW OVERVIEW The instruction set used by the Am186 and Am188 family of microcontrollers is identical to the original 8086 and 8088 instruction set, with the addition of seven instructions (BOUND, ENTER, INS, LEAVE, OUTS, POPA, and PUSHA), and the enhancement of nine instructions (immediate operands were added to IMUL, PUSH, RCL, RCR, ROL, ROR, SAL/SHL, SAR, and SHR). In addition, three valid instructions are not supported with the necessary processor pinout (ESC, LOCK and WAIT). All of these instructions are marked as such in their description. 2.2 INSTRUCTION FORMAT When assembling code, an assembler replaces each instruction statement with its machine-language equivalent. In machine language, all instructions conform to one basic format. However, the length of an instruction in machine language varies depending on the operands used in the instruction and the operation that the instruction performs. An instruction can reference from zero to several operands. An operand can reside in a register, in the instruction itself, or in memory. The Am186 and Am188 microcontrollers use the following instruction format. The shortest instructions consist of only a single opcode byte. Instruction Prefixes Segment Override Prefix Opcode Operand Address Displacement Immediate 2.2.1 Instruction Prefixes The REP, REPE, REPZ, REPNE and REPNZ prefixes can be used to repeatedly execute a single string instruction. The LOCK prefix may be combined with the instruction and segment override prefixes, and causes the processor to assert its bus LOCK signal while the instruction that follows executes. Instruction Set Overview 2-1 2.2.2 Segment Override Prefix To override the default segment register, place the following byte in front of the instruction, where RR determines which register is used. Only one segment override prefix can be used per instruction. Segment Override Prefix 0 0 1 R R 1 1 0 7 6 5 4 3 1 0 2 00 = ES Register 01 = CS Register 10 = SS Register 11 = DS Register 2.2.3 Opcode This specifies the machine-language opcode for an instruction. The format for the opcodes is described on page 2-5. Although most instructions use only one opcode byte, the AAD (D5 0A hex) and AAM (D4 0A hex) instructions use two opcodes. 2.2.4 Operand Address The following illustration shows the structure of the operand address byte. The operand address byte controls the addressing for an instruction. Along with r/m, the Modifier field determines whether the Register/Memory field is interpreted as a register or the address of a memory operand. For a memory operand, the Modifier field also indicates whether the operand is addressed directly or indirectly. For indirectly addressed memory operands, the Modifier field specifies the number of bytes of displacement that appear in the instruction. See Table 2-1 for mod values. Along with mod, the Register/Memory field specifies a general register or the address of a memory operand. See Table 2-3 for r/m values. Operand Address mod 7 6 aux 5 4 r/m 3 2 1 0 The Auxiliary field specifies an opcode extension or a register that is used as a second operand. See Table 2-2 for aux values Table 2-1 2-2 mod field mod Description 11 r/m is treated as a reg field 00 DISP = 0, disp-low and disp-high are absent 01 DISP = disp-low sign-extended to 16-bits, disp-high is absent 10 DISP = disp-high: disp-low Instruction Set Overview Table 2-2 aux field aux If mod=11 and w=0 If mod=11 and w=1 000 AL AX 001 CL CX 010 DL DX 011 BL BX 100 AH SP 101 CH BP 110 DH SI 111 BH DI * – When mod≠11, depends on instruction Table 2-3 r/m field r/m Description 000 EA* = (BX)+(SI)+DISP 001 EA = (BX)+(DI)+DISP 010 EA = (BP)+(SI)+DISP 011 EA = (BP)+(DI)+DISP 100 EA = (SI)+DISP 101 EA = (DI)+DISP 110 EA = (BP)+DISP (except if mod=00, then EA = disp-high:disp:low) 111 EA = (BX)+DISP * – EA is the Effective Address 2.2.5 Displacement The displacement is an 8- or 16-bit immediate value to be added to the offset portion of the address. 2.2.6 Immediate The immediate bytes contain up to 16 bits of immediate data. 2.3 NOTATION This parameter Indicates that : The component on the left is the segment for a component located in memory. The component on the right is the offset. :: The component on the left is concatenated with the component on the right. Instruction Set Overview 2-3 2.4 USING THIS MANUAL Each instruction is detailed in Chapter 4. The following sections explain the format used when describing each instruction. 2.4.1 Mnemonics and Names The primary assembly-language mnemonic and its name appear at the top of the first page for an instruction (see Figure 2-1). Some instructions have additional mnemonics that perform the same operation. These synonyms are listed below the primary mnemonic. Figure 2-1 Instruction Mnemonic and Name Sample MUL Multiply Unsigned Numbers 2.4.2 Forms of the Instruction Many instructions have more than one form. The forms for each instruction are listed in a table just below the mnemonics (see Figure 2-2). Figure 2-2 Instruction Forms Table Sample Clocks Am186 Am188 Form Opcode Description MUL r/m8 F6 /4 AX=(r/m byte)•AL 26–28/32–34 26–28/32–34 MUL r/m16 F7 /4 DX::AX=(r/m word)•AX 35–37/41–43 35–37/45–47 Form The Form column specifies the syntax for the different forms of an instruction. Each form includes an instruction mnemonic and zero or more operands. Items in italics are placeholders for operands that must be provided. A placeholder indicates the size and type of operand that is allowed. This operand imm8 imm16 m m8 m16 m16&16 m16:16 moffs8 moffs16 ptr16:16 r8 r16 r/m8 r/m16 rel8 rel16 sreg 2-4 Is a placeholder for An immediate byte: a signed number between –128 and 127 An immediate word: a signed number between –32768 and 32767 An operand in memory A byte string in memory pointed to by DS:SI or ES:DI A word string in memory pointed to by DS:SI or ES:DI A pair of words in memory A doubleword in memory that contains a full address (segment:offset) A byte in memory that contains a signed, relative offset displacement A word in memory that contains a signed, relative offset displacement A full address (segment:offset) A general byte register: AL, BL, CL, DL, AH, BH, CH, or DH A general word register: AX, BX, CX, DX, BP, SP, DI, or SI A general byte register or a byte in memory A general word register or a word in memory A signed, relative offset displacement between –128 and 127 A signed, relative offset displacement between –32768 and 32767 A segment register Instruction Set Overview Opcode The Opcode column specifies the machine-language opcodes for the different forms of an instruction. (For instruction prefixes, this column also includes the prefix.) Each opcode includes one or more numbers in hexadecimal format, and zero or more parameters, which are shown in italics. A parameter provides information about the contents of the Operand Address byte for that particular form of the instruction. This parameter Indicates that /0–/7 The Auxiliary (aux) Field in the Operand Address byte specifies an extension (from 0 to 7) to the opcode instead of a register. So for example, the opcode for adding (ADD) an immediate byte to a general byte register or a byte in memory is "80 /0 ib". So the second byte of the opcode is "mod 000 r/m", where mod and r/m are as defined in "Operand Address" on page 2-2. /0 The aux field is 0. /1 The aux field is 1. /2 The aux field is 2. /3 The aux field is 3. /4 The aux field is 4. /5 The aux field is 5. /6 The aux field is 6. /7 The aux field is 7. /r The Auxiliary (aux) field in the Operand Address byte specifies a register instead of an opcode extension. If the Opcode byte specifies a byte register, the registers are assigned as follows: AL=0, CL=1, DL=2, BL=3, AH=4, CH=5, DH=6, and BH=7. If the Opcode byte specifies a word register, the registers are assigned as follows: AX=0, CX=1, DX=2, BX=3, SP=4, BP=5, SI=6, and DI=7. /sr The Auxiliary (aux) field in the Operand Address byte specifies a segment register as follows: ES=0, CS=1, SS=2, and DS=3. cb The byte following the Opcode byte specifies an offset. cd The doubleword following the Opcode byte specifies an offset and, in some cases, a segment. cw The word following the Opcode byte specifies an offset and, in some cases, a segment. ib The parameter is an immediate byte. The Opcode byte determines whether it is interpreted as a signed or unsigned number. iw The parameter is an immediate word. The Opcode byte determines whether it is interpreted as a signed or unsigned number. rb The byte register operand is specified in the Opcode byte. To determine the Opcode byte for a particular register, add the hexadecimal value on the left of the plus sign to the value of rb for that register, as follows: AL=0, CL=1, DL=2, BL= 3, AH=4, CH=5, DH=6, and BH=7. So for example, the opcode for moving an immediate byte to a register (MOV) is "B0+rb". So B0–B7 are valid opcodes, and B0 is "MOV AL,imm8". rw The word register operand is specified in the Opcode byte. To determine the Opcode byte for a particular register, add the hexadecimal value on the left of the plus sign to the value of rw for that register, as follows: AX=0, CX=1, DX=2, BX=3, SP=4, BP=5, SI=6, DI=7. Instruction Set Overview 2-5 Description The Description column contains a brief synopsis of each form of the instruction. Clocks The Clocks columns (one for the Am186 and one for the Am188 microcontrollers) specify the number of clock cycles required for the different forms of an instruction. 2.4.3 This parameter Indicates that / The number of clocks required for a register operand is different than the number required for an operand located in memory. The number to the left corresponds with a register operand; the number to the right corresponds with an operand located in memory. , The number of clocks depends on the result of the condition tested. The number to the left corresponds with a True or Pass result, and the number to the right corresponds with a False or Fail result. n The number of clocks depends on the number of times the instruction is repeated. n is the number of repetitions. What It Does This section contains a brief description of the operation the instruction performs. 2.4.4 Syntax This section shows the syntax for the instruction. Instructions with more than one mnemonic show the syntax for each mnemonic. 2.4.5 Description This section contains a more in-depth description of the instruction. 2-6 Instruction Set Overview 2.4.6 Operation It Performs This section uses a combination of C-language and assembler syntax to describe the operation of the instruction in detail. In some cases, pseudo-code functions are used to simplify the code. These functions and the actions they perform are as follows: Pseudo-Code Function cat(componenta,componentb) execute(instruction) interrupt(type) interruptRequest() leastSignificantBit(component) mostSignificantBit(component) nextMostSignificantBit(component) nmiRequest() operands() pop() pow(n,component) push(component) resetRequest() serviceInterrupts() size(component) stopExecuting() 2.4.7 Action Component A is concatenated with component B. Execute the instruction. Issue an interrupt request to the microcontroller. Return True if the microcontroller receives a maskable interrupt request. Return the least significant bit of the component. Return the most significant bit of the component. Return the next most significant bit of the component. Return True if the microcontroller receives a nonmaskable interrupt request. Return the number of operands present in the instruction. Read a word from the top of the stack, increment SP, and return the value. Raise component to the nth power. Decrement SP and copy the component to the top of the stack. Return True if a device resets the microcontroller by asserting the RES signal. Service any pending interrupts. Return the size of the component in bits. Suspend execution of current instruction sequence. Flag Settings After Instruction This section identifies the flags that are set, cleared, modified according to the result, unchanged, or left undefined by the instruction. Each instruction has the graphic below, and shows values for the flag bits after the instruction is performed. A "?" in the bit field indicates the value is undefined; a "–" indicates the bit value is unchanged. See "Processor Status Flags Register" on page 1-2 for more information on the flags. Processor Status Flags Register OF DF IF TF SF ZF 11 9 res reserved 15 14 13 12 10 8 7 ? = undefined; – = unchanged 2.4.8 AF 6 5 PF res 4 3 CF res 2 1 0 ? = unknown; – = unchanged Examples This section contains one or more examples that illustrate possible uses for the instruction. The beginning of each example is marked with a printout icon; a summary of the example’s function appears next to it. The example code follows the summary. Note that some of the examples use assembler directives: CONST (define constant data), DB (define byte), DD (define double), DW (define word), EQU (equate), LENGTH (length of array), PROC (begin procedure), SEGMENT (define segment), SIZE (return integer size) and TYPE (return integer type). Instruction Set Overview 2-7 2.4.9 Tips This section contains hints and ideas about some of the ways in which the instruction can be used. Tips are marked with this icon. 2.4.10 Related Instructions This section lists other instructions related to the described instruction. 2-8 Instruction Set Overview CHAPTER 3 INSTRUCTION SET LISTING This chapter lists all the instructions for the Am186 and Am188 family of microcontrollers. The instructions are first grouped by type (see page 3-1) and then listed in alphabetical order (see page 3-11) 3.1 INSTRUCTION SET BY TYPE The instructions can be classified into groups according to the type of operation they perform. Instructions that are used for more than one purpose are listed under each category to which they belong. The functional groups are: n "Address Calculation and Translation" on page 3-1 n "Binary Arithmetic" on page 3-2 n "Block-Structured Language" on page 3-3 n "Comparison" on page 3-3 n "Control Transfer" on page 3-3 n "Data Movement" on page 3-5 n "Decimal Arithmetic" on page 3-6 n "Flag" on page 3-7 n "Input/Output" on page 3-8 n "Logical Operation" on page 3-8 n "Processor Control" on page 3-9 n "String" on page 3-9 3.1.1 Address Calculation and Translation Address Calculation Instructions Mnemonic Name See Page LDS Load DS with Segment and Register with Offset 4-131 LEA Load Effective Address 4-133 LES Load ES with Segment and Register with Offset 4-138 Address Translation Instructions Mnemonic Name See Page XLAT Translate Table Index to Component 4-248 XLATB Translate Table Index to Byte (Synonym for XLAT) 4-248 Instruction Set Listing 3-1 3.1.2 Binary Arithmetic The microcontroller supports binary arithmetic using numbers represented in the two’s complement system. The two’s complement system uses the high bit of an integer (a signed number) to determine the sign of the number. Unsigned numbers have no sign bit. Binary Addition Instructions Mnemonic Name See Page ADC Add Numbers with Carry 4-10 ADD Add Numbers 4-14 INC Increment Number by One 4-69 Binary Subtraction Instructions Mnemonic Name See Page DEC Decrement Number by One 4-48 SBB Subtract Numbers with Borrow 4-216 SUB Subtract Numbers 4-240 Binary Multiplication Instructions Mnemonic Name See Page IMUL Multiply Integers 4-63 MUL Multiply Unsigned Numbers 4-160 SAL Shift Arithmetic Left 4-211 SHL Shift Left (Synonym for SAL) 4-211 Binary Division Instructions Mnemonic Name See Page DIV Divide Unsigned Numbers 4-50 IDIV Divide Integers 4-60 SAR Shift Arithmetic Right 4-214 SHR Shift Right 4-225 Binary Conversion Instructions 3-2 Mnemonic Name See Page CBW Convert Byte Integer to Word 4-24 CWD Convert Word Integer to Doubleword 4-40 NEG Two’s Complement Negation 4-163 Instruction Set Listing 3.1.3 Block-Structured Language Block-Structured Language Instructions 3.1.4 Mnemonic Name See Page ENTER Enter High-Level Procedure 4-53 LEAVE Leave High-Level Procedure 4-135 Comparison General Comparison Instructions Mnemonic Name See Page CMP Compare Components 4-34 TEST Logical Compare 4-243 String Comparison Instructions 3.1.5 Mnemonic Name See Page CMPS Compare String Components 4-36 CMPSB Compare String Bytes (Synonym for CMPS) 4-36 CMPSW Compare String Words (Synonym for CMPS) 4-36 SCAS Scan String for Component 4-219 SCASB Scan String for Byte (Synonym for SCAS) 4-219 SCASW Scan String for Word (Synonym for SCAS) 4-219 Control Transfer Conditional Jump Instructions to Use after Integer Comparisons Mnemonic Name See Page JG Jump If Greater 4-91 JGE Jump If Greater or Equal 4-93 JL Jump If Less 4-95 JLE Jump If Less or Equal 4-97 JNG Jump If Not Greater (Synonym for JLE) 4-97 JNGE Jump If Not Greater or Equal (Synonym for JL) 4-95 JNL Jump If Not Less (Synonym for JGE) 4-93 JNLE Jump If Not Less or Equal (Synonym for JG) 4-91 Instruction Set Listing 3-3 Conditional Jump Instructions to Use after Unsigned Number Comparisons Mnemonic Name See Page JA Jump If Above 4-78 JAE Jump If Above or Equal 4-80 JB Jump If Below 4-82 JBE Jump If Below or Equal 4-84 JNA Jump If Not Above (Synonym for JBE) 4-84 JNAE Jump If Not Above or Equal (Synonym for JB) 4-82 JNB Jump If Not Below (Synonym for JAE) 4-80 JNBE Jump If Not Below or Equal (Synonym for JA) 4-78 Conditional Jump Instructions That Test for Equality Mnemonic Name See Page JE Jump If Equal 4-89 JNE Jump If Not Equal 4-107 Conditional Jump Instructions That Test Flags Mnemonic Name See Page JC Jump If Carry (Synonym for JB) 4-82 JNC Jump If Not Carry (Synonym for JAE) 4-80 JNO Jump If Not Overflow 4-113 JNP Jump If Not Parity (Synonym for JPO) 4-124 JNS Jump If Not Sign 4-116 JNZ Jump If Not Zero (Synonym for JNE) 4-107 JO Jump If Overflow 4-119 JP Jump If Parity (Synonym for JPE) 4-121 JPE Jump If Parity Even 4-122 JPO Jump If Parity Odd 4-124 JS Jump If Sign 4-126 JZ Jump If Zero (Synonym for JE) 4-89 Conditional Interrupt Instructions 3-4 Mnemonic Name See Page BOUND Check Array Index Against Bounds 4-19 IDIV Divide Integers 4-60 INTO Generate Interrupt If Overflow (Conditional form of INT) 4-73 Instruction Set Listing Conditional Loop Instructions Mnemonic Name See Page JCXZ Jump If CX Register Is Zero 4-87 LOOP Loop While CX Register is Not Zero 4-146 LOOPE Loop If Equal 4-148 LOOPNE Loop If Not Equal 4-150 LOOPNZ Loop If Not Zero (Synonym for LOOPNE) 4-150 LOOPZ Loop If Zero (Synonym for LOOPE) 4-148 Unconditional Transfer Instructions 3.1.6 Mnemonic Name See Page CALL Call Procedure 4-21 INT Generate Interrupt 4-73 IRET Interrupt Return 4-76 JMP Jump Unconditionally 4-99 RET Return from Procedure 4-202 Data Movement General Movement Instructions Mnemonic Name See Page MOV Move Component 4-153 XCHG Exchange Components 4-246 String Movement Instructions Mnemonic Name See Page LODS Load String Component 4-141 LODSB Load String Byte (Synonym for LODS) 4-141 LODSW Load String Word (Synonym for LODS) 4-141 MOVS Move String Component 4-156 MOVSB Move String Byte (Synonym for MOVS) 4-156 MOVSW Move String Word (Synonym for MOVS) 4-156 STOS Store String Component 4-237 STOSB Store String Byte (Synonym for STOS) 4-237 STOSW Store String Word (Synonym for STOS) 4-237 Instruction Set Listing 3-5 Stack Movement Instructions Mnemonic Name See Page POP Pop Component from Stack 4-175 POPA Pop All 16-Bit General Registers from Stack 4-178 POPF Pop Flags from Stack 4-180 PUSH Push Component onto Stack 4-181 PUSHA Push All 16-Bit General Registers onto Stack 4-184 PUSHF Push Flags onto Stack 4-186 General I/O Movement Instructions Mnemonic Name See Page IN Input Component from Port 4-67 OUT Output Component to Port 4-171 String I/O Movement Instructions Mnemonic Name See Page INS Input String Component from Port 4-71 INSB Input String Byte from Port (Synonym for INS) 4-71 INSW Input String Word from Port (Synonym for INS) 4-71 OUTS Output String Component to Port 4-173 OUTSB Output String Byte to Port (Synonym for OUTS) 4-173 OUTSW Output String Word to Port (Synonym for OUTS) 4-173 Flag Movement Instructions 3.1.7 Mnemonic Name See Page LAHF Load AH with Flags 4-129 SAHF Store AH in Flags 4-209 Decimal Arithmetic In addition to binary arithmetic, the microcontroller supports arithmetic using numbers represented in the binary-coded decimal (BCD) system. The BCD system uses four bits to represent a single decimal digit. When two decimal digits are stored in a byte, the number is called a packed decimal number. When only one decimal digit is stored in a byte, the number is called an unpacked decimal number. To perform decimal arithmetic, the microcontroller uses a subset of the binary arithmetic instructions and a special set of instructions that convert unsigned binary numbers to decimal. Arithmetic Instructions That Are Used with Decimal Numbers 3-6 Mnemonic Name See Page ADD Add Numbers 4-14 DIV Divide Unsigned Numbers 4-50 MUL Multiply Unsigned Numbers 4-160 SUB Subtract Numbers 4-240 Instruction Set Listing Unpacked-Decimal Adjustment Instructions Mnemonic Name See Page AAA ASCII Adjust AL After Addition 4-2 AAD ASCII Adjust AX Before Division 4-4 AAM ASCII Adjust AL After Multiplication 4-6 AAS ASCII Adjust AL After Subtraction 4-8 Packed-Decimal Adjustment Instructions Mnemonic Name See Page DAA Decimal Adjust AL After Addition 4-42 DAS Decimal Adjust AL After Subtraction 4-45 Consider using decimal arithmetic instead of binary arithmetic under the following circumstances: n When the numbers you are using represent only decimal quantities. Manipulating numbers in binary and converting them back and forth between binary and decimal can introduce rounding errors. n When you need to read or write many ASCII numbers. Converting a number between ASCII and decimal is simpler than converting it between ASCII and binary. 3.1.8 Flag Single-Flag Instructions Mnemonic Name See Page CLC Clear Carry Flag 4-26 CLD Clear Direction Flag 4-29 CLI Clear Interrupt-Enable Flag 4-31 CMC Complement Carry Flag 4-33 RCL Rotate through Carry Left 4-187 RCR Rotate through Carry Right 4-189 STC Set Carry Flag 4-228 STD Set Direction Flag 4-231 STI Set Interrupt-Enable Flag 4-235 Multiple-Flag Instructions Mnemonic Name See Page POPF Pop Flags from Stack 4-180 SAHF Store AH in Flags 4-209 Instruction Set Listing 3-7 3.1.9 Input/Output General I/O Instructions Mnemonic Name See Page IN Input Component from Port 4-67 OUT Output Component to Port 4-171 String I/O Instructions 3.1.10 Mnemonic Name See Page INS Input String Component from Port 4-71 INSB Input String Byte from Port (Synonym for INS) 4-71 INSW Input String Word from Port (Synonym for INS) 4-71 OUTS Output String Component to Port 4-173 OUTSB Output String Byte to Port (Synonym for OUTS) 4-173 OUTSW Output String Word to Port (Synonym for OUTS) 4-173 Logical Operation Boolean Operation Instructions Mnemonic Name See Page AND Logical AND 4-17 NOT One’s Complement Negation 4-167 OR Logical Inclusive OR 4-169 XOR Logical Exclusive OR 4-251 Shift Instructions Mnemonic Name See Page SAL Shift Arithmetic Left 4-211 SAR Shift Arithmetic Right 4-214 SHL Shift Left (Synonym for SAL) 4-211 SHR Shift Right 4-225 Rotate Instructions 3-8 Mnemonic Name See Page RCL Rotate through Carry Left 4-187 RCR Rotate through Carry Right 4-189 ROL Rotate Left 4-205 ROR Rotate Right 4-207 Instruction Set Listing 3.1.11 Processor Control Processor Control Instructions Mnemonic Name See Page HLT Halt 4-57 LOCK Lock the Bus 4-140 NOP No Operation 4-165 Coprocessor Interface Instructions 3.1.12 Mnemonic Name See Page ESC Escape 4-56 WAIT Wait for Coprocessor 4-245 String A string is a contiguous sequence of components stored in memory. For example, a string might be composed of a list of ASCII characters or a table of numbers. A string instruction operates on a single component in a string. To manipulate more than one component in a string, the string instruction prefixes (REP/REPE/REPNE/REPNZ/ REPZ) can be used to repeatedly execute the same string instruction. A string instruction uses an index register as the offset of a component in a string. Most string instructions operate on only one string, in which case they use either the Source Index (SI) register or the Destination Index (DI) register. String instructions that operate on two strings use SI as the offset of a component in one string and DI as the offset of the corresponding component in the other string. After executing a string instruction, the microcontroller automatically increments or decrements SI and DI so that they contain the offsets of the next components in their strings. The microcontroller determines the amount by which the index registers must be incremented or decremented based on the size of the components. The microcontroller can process the components of a string in a forward direction (from lower addresses to higher addresses), or in a backward direction (from higher addresses to lower ones). The microcontroller uses the value of the Direction Flag (DF) to determine whether to increment or decrement SI and DI. If DF is cleared to 0, the microcontroller increments the index registers; otherwise, it decrements them. String-Instruction Prefixes Mnemonic Name See Page REP Repeat 4-191 REPE Repeat While Equal 4-193 REPNE Repeat While Not Equal 4-197 REPNZ Repeat While Not Zero (Synonym for REPNE) 4-197 REPZ Repeat While Zero (Synonym for REPE) 4-193 Instruction Set Listing 3-9 String Direction Instructions Mnemonic Name See Page CLD Clear Direction Flag 4-29 STD Set Direction Flag 4-231 String Movement Instructions Mnemonic Name See Page LODS Load String Component 4-141 LODSB Load String Byte (Synonym for LODS) 4-141 LODSW Load String Word (Synonym for LODS) 4-141 MOVS Move String Component 4-156 MOVSB Move String Byte (Synonym for MOVS) 4-156 MOVSW Move String Word (Synonym for MOVS) 4-156 STOS Store String Component 4-237 STOSB Store String Byte (Synonym for STOS) 4-237 STOSW Store String Word (Synonym for STOS) 4-237 String Comparison Instructions Mnemonic Name See Page CMPS Compare String Components 4-36 CMPSB Compare String Bytes (Synonym for CMPS) 4-36 CMPSW Compare String Words (Synonym for CMPS) 4-36 SCAS Scan String for Component 4-219 SCASB Scan String for Byte (Synonym for SCAS) 4-219 SCASW Scan String for Word (Synonym for SCAS) 4-219 String I/O Instructions 3-10 Mnemonic Name See Page INS Input String Component from Port 4-71 INSB Input String Byte from Port (Synonym for INS) 4-71 INSW Input String Word from Port (Synonym for INS) 4-71 OUTS Output String Component to Port 4-173 OUTSB Output String Byte to Port (Synonym for OUTS) 4-173 OUTSW Output String Word to Port (Synonym for OUTS) 4-173 Instruction Set Listing 3.2 INSTRUCTION SET IN ALPHABETICAL ORDER Table 3-1 provides an alphabetical list of the instruction set for the Am186 and Am188 microcontrollers. Table 3-1 Instruction Set Mnemonic AAA AAD AAM AAS ADC ADD AND BOUND CALL CBW CLC CLD CLI CMC CMP CMPS CMPSB CMPSW CWD DAA DAS DEC DIV ENTER ESC HLT IDIV IMUL IN INC INS INSB INSW INT INTO IRET JA JAE JB JBE JC JCXZ Instruction Name ASCII Adjust AL After Addition ASCII Adjust AX Before Division ASCII Adjust AL After Multiplication ASCII Adjust AL After Subtraction Add Numbers with Carry Add Numbers Logical AND Check Array Index Against Bounds Call Procedure Convert Byte Integer to Word Clear Carry Flag Clear Direction Flag Clear Interrupt-Enable Flag Complement Carry Flag Compare Components Compare String Components Compare String Bytes (Synonym for CMPS) Compare String Words (Synonym for CMPS) Convert Word Integer to Doubleword Decimal Adjust AL After Addition Decimal Adjust AL After Subtraction Decrement Number by One Divide Unsigned Numbers Enter High-Level Procedure Escape Halt Divide Integers Multiply Integers Input Component from Port Increment Number by One Input String Component from Port Input String Byte from Port (Synonym for INS) Input String Word from Port (Synonym for INS) Generate Interrupt Generate Interrupt If Overflow (Conditional form of INT) Interrupt Return Jump If Above Jump If Above or Equal Jump If Below Jump If Below or Equal Jump If Carry (Synonym for JB) Jump If CX Register Is Zero Instruction Set Listing See Page 4-2 4-4 4-6 4-8 4-10 4-14 4-17 4-19 4-21 4-24 4-26 4-29 4-31 4-33 4-34 4-36 4-36 4-36 4-40 4-42 4-45 4-48 4-50 4-53 4-56 4-57 4-60 4-63 4-67 4-69 4-71 4-71 4-71 4-73 4-73 4-76 4-78 4-80 4-82 4-84 4-82 4-87 3-11 Table 3-1 Instruction Set (continued) Mnemonic JE JG JGE JL JLE JMP JNA JNAE JNB JNBE JNC JNE JNG JNGE JNL JNLE JNO JNP JNS JNZ JO JP JPE JPO JS JZ LAHF LDS LEA LEAVE LES LOCK LODS LODSB LODSW LOOP LOOPE LOOPNE LOOPNZ LOOPZ MOV MOVS MOVSB MOVSW MUL NEG NOP 3-12 Instruction Name Jump If Equal Jump If Greater Jump If Greater or Equal Jump If Less Jump If Less or Equal Jump Unconditionally Jump If Not Above (Synonym for JBE) Jump If Not Above or Equal (Synonym for JB) Jump If Not Below (Synonym for JAE) Jump If Not Below or Equal (Synonym for JA) Jump If Not Carry (Synonym for JAE) Jump If Not Equal Jump If Not Greater (Synonym for JLE) Jump If Not Greater or Equal (Synonym for JL) Jump If Not Less (Synonym for JGE) Jump If Not Less or Equal (Synonym for JG) Jump If Not Overflow Jump If Not Parity (Synonym for JPO) Jump If Not Sign Jump If Not Zero (Synonym for JNE) Jump If Overflow Jump If Parity (Synonym for JPE) Jump If Parity Even Jump If Parity Odd Jump If Sign Jump If Zero (Synonym for JE) Load AH with Flags Load DS with Segment and Register with Offset Load Effective Address Leave High-Level Procedure Load ES with Segment and Register with Offset Lock the Bus Load String Component Load String Byte (Synonym for LODS) Load String Word (Synonym for LODS) Loop While CX Register Is Not Zero Loop If Equal Loop If Not Equal Loop If Not Zero (Synonym for LOOPNE) Loop If Zero (Synonym for LOOPE) Move Component Move String Component Move String Byte (Synonym for MOVS) Move String Word (Synonym for MOVS) Multiply Unsigned Numbers Two’s Complement Negation No Operation Instruction Set Listing See Page 4-89 4-91 4-93 4-95 4-97 4-99 4-84 4-82 4-80 4-78 4-80 4-107 4-97 4-95 4-93 4-91 4-113 4-124 4-116 4-107 4-119 4-122 4-122 4-124 4-126 4-89 4-129 4-131 4-133 4-135 4-138 4-140 4-141 4-141 4-141 4-146 4-148 4-150 4-150 4-148 4-153 4-156 4-156 4-156 4-160 4-163 4-165 Table 3-1 Instruction Set (continued) Mnemonic NOT OR OUT OUTS OUTSB OUTSW POP POPA POPF PUSH PUSHA PUSHF RCL RCR REP REPE REPNE REPNZ REPZ RET ROL ROR SAHF SAL SAR SBB SCAS SCASB SCASW SHL SHR STC STD STI STOS STOSB STOSW SUB TEST WAIT XCHG XLAT XLATB XOR Instruction Name One’s Complement Negation Logical Inclusive OR Output Component to Port Output String Component to Port Output String Byte to Port (Synonym for OUTS) Output String Word to Port (Synonym for OUTS) Pop Component from Stack Pop All 16-Bit General Registers from Stack Pop Flags from Stack Push Component onto Stack Push All 16-Bit General Registers onto Stack Push Flags onto Stack Rotate through Carry Left Rotate through Carry Right Repeat Repeat While Equal Repeat While Not Equal Repeat While Not Zero (Synonym for REPNE) Repeat While Zero (Synonym for REPE) Return from Procedure Rotate Left Rotate Right Store AH in Flags Shift Arithmetic Left Shift Arithmetic Right Subtract Numbers with Borrow Scan String for Component Scan String for Byte (Synonym for SCAS) Scan String for Word (Synonym for SCAS) Shift Left (Synonym for SAL) Shift Right Set Carry Flag Set Direction Flag Set Interrupt-Enable Flag Store String Component Store String Byte (Synonym for STOS) Store String Word (Synonym for STOS) Subtract Numbers Logical Compare Wait for Coprocessor Exchange Components Translate Table Index to Component Translate Table Index to Byte (Synonym for XLAT) Logical Exclusive OR Instruction Set Listing See Page 4-167 4-169 4-171 4-173 4-173 4-173 4-175 4-178 4-180 4-181 4-184 4-186 4-187 4-189 4-191 4-193 4-197 4-197 4-193 4-202 4-205 4-207 4-209 4-211 4-214 4-216 4-219 4-219 4-219 4-211 4-225 4-228 4-231 4-235 4-237 4-237 4-237 4-240 4-243 4-245 4-246 4-248 4-248 4-251 3-13 3-14 Instruction Set Listing CHAPTER 4 4.1 INSTRUCTION SET INSTRUCTIONS This chapter contains a complete description of each instruction that is supported by the Am186 and Am188 family of microcontrollers. For an explanation of the format of each instruction, see Chapter 2. Instruction Set 4-1 AAA ASCII Adjust AL After Addition AAA Clocks Am186 Am188 Form Opcode Description AAA 37 ASCII-adjust AL after addition 8 8 What It Does AAA converts an 8-bit unsigned binary number that is the sum of two unpacked decimal (BCD) numbers to its unpacked decimal equivalent. Syntax AAA Description Use the AAA instruction after an ADD or ADC instruction that leaves a byte result in the AL register. The lower nibbles of the operands of the ADD or ADC instruction should be in the range 0–9 (BCD digits). The AAA instruction adjusts the AL register to contain the correct decimal digit result. If the addition produced a decimal carry, AAA increments the AH register and sets the Carry and Auxiliary-Carry Flags (CF and AF). If there is no decimal carry, AAA clears CF and AF and leaves the AH register unchanged. AAA sets the top nibble of the AL register to 0. Operation It Performs if (((AL = AL & 0x0F) > 9) || (AF == 1)) /* AL is not yet in BCD format */ /* (note high nibble of AL is cleared either way) */ { /* convert AL to decimal and unpack */ AL = (AL + 6) & 0x0F; AH = AH + 1; /* set carry flags */ CF = AF = 1; } else /* clear carry flags */ CF = AF = 0; Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF ? – – – ? ? res 11 10 9 8 7 6 5 PF CF res ? res 4 3 2 1 0 ? = undefined; – = unchanged AF=1 if carry or borrow to low nibble CF=1 for carry or borrow to high-order bit AF=0 otherwise CF=0 otherwise 4-2 Instruction Set AAA AAA Examples This example adds two unpacked decimal numbers. UADDEND1 UADDEND2 DB DB 05h 07h ; add unpacked decimal numbers XOR AX,AX MOV AL,UADDEND1 ADD AL,UADDEND2 AAA ; the AF and CF flags will be set, ; 5 unpacked BCD ; 7 unpacked BCD ; clear AX ; AL = 05h = 5 ; AX = 000Ch = ; AX = 0102h = indicating the unpacked BCD 12 12 unpacked BCD carry into AH Tips To convert an unpacked decimal digit to its ASCII equivalent, use OR after AAA to add 30h (ASCII 0) to the digit. ADC, ADD, SBB, and SUB set AF when the result needs to be converted for decimal arithmetic. AAA, AAS, DAA, and DAS use AF to determine whether an adjustment is needed. This is the only use for AF. Related Instructions If you want to See Add two numbers and the value of CF Add two numbers ADC ADD Convert an 8-bit unsigned binary sum to its packed decimal equivalent DAA Instruction Set 4-3 AAD ASCII Adjust AX Before Division AAD Clocks Am186 Am188 Form Opcode Description AAD D5 0A ASCII-adjust AX before division 15 15 What It Does AAD converts a two-digit unpacked decimal (BCD) number—ordinarily the dividend of an unpacked decimal division—to its unsigned binary equivalent. Syntax AAD Description AAD prepares two unpacked BCD digits—the least significant digit in the AL register and the most significant digit in the AH register—for division by an unpacked BCD digit. The instruction sets the AL register to AL + (10•AH) and then clears the AH register. The AX register then equals the binary equivalent of the original unpacked two-digit number. Operation It Performs /* convert AX to binary */ AL = (AH * 10) + AL; AH = 0; Flag Settings After Instruction OF DF Processor Status Flags Register ? – – – 11 10 9 8 reserved 15 14 13 12 IF TF SF ZF AF PF res ? res 7 6 5 4 3 CF res ? 2 1 0 ? = undefined; – = unchanged SF=1 if result is 0 or positive SF=0 if result is negative ZF=1 if result equal to 0 ZF=0 if result not equal to 0 PF=1 if low byte of result has even number of set bits PF=0 otherwise Examples This example divides a two-digit unpacked decimal number by a one-digit unpacked decimal number. UDIVIDEND UDIVISOR DW DB 0409h 03h ; 49 unpacked BCD ; 3 unpacked BCD ; divide unpacked decimal numbers (two digit by one digit) MOV AX,UDIVIDEND ; AX = 0409h = 49 unpacked BCD AAD ; AX = 0031h = 49 DIV UDIVISOR ; AL = 10h = 16, the quotient ; AH = 01h = 1, the remainder MOV BL,AH ; save remainder, BL = 01h = 1 AAM ; AX = 0106h = 16 unpacked BCD 4-4 Instruction Set AAD AAD This example uses AAD to convert a two-digit unpacked decimal number to its binary equivalent. UBCD DW 0801h ; 81 unpacked BCD ; convert unpacked decimal number to binary MOV AX,UBCD ; AX = 0801h = 81 unpacked BCD AAD ; AX = 0051h = 81 Tips The microcontroller can only divide unpacked decimal numbers. To divide packed decimal numbers, unpack them first. Related Instructions If you want to See Divide an unsigned number by another unsigned number DIV Instruction Set 4-5 AAM ASCII Adjust AL After Multiplication AAM Clocks Am186 Am188 Form Opcode Description AAM D4 0A ASCII-adjust AL after multiplication 19 19 What It Does AAM converts an 8-bit unsigned binary number—ordinarily the product of two unpacked decimal (BCD) numbers—to its unpacked decimal equivalent. Syntax AAM Description Use AAM only after executing the MUL instruction between two unpacked BCD operands with the result in the AX register. Because the result is 99 or less, it resides 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. Operation It Performs /* convert AL to decimal */ AH = AL / 10; AL = AL % 10; Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF ? – – – 11 10 9 8 AF PF res ? res 7 6 5 4 3 CF res ? 2 1 0 ? = undefined; – = unchanged SF=1 if result is 0 or positive SF=0 if result is negative ZF=1 if result equal to 0 ZF=0 if result not equal to 0 PF=1 if low byte of result has even number of set bits PF=0 otherwise Examples This example multiplies two unpacked decimal digits. UMULTIPLICAND UMULTIPLIER DB DB 07h 06h ; 7 unpacked BCD ; 6 unpacked BCD ; multiply unpacked decimal numbers MOV AL,UMULTIPLICAND ; AL = 07h = 7 unpacked BCD MUL UMULTIPLIER ; AL = 2Ah = 42 AAM ; AX = 0402h = 42 unpacked BCD 4-6 Instruction Set AAM AAM This example uses AAM to divide an unsigned binary number by 10. (The binary number must be 99 or less.) Note that the quotient occupies the high byte of the result, and the remainder occupies the low byte of the result. If you use DIV to divide an unsigned number by 10, the quotient and remainder occupy the opposite halves of the result. UBINARY DB 44h ; 68 ; divide unsigned binary number by 10 MOV AL,UBINARY ; AL = 44h = 68 AAM ; AH = 06h = 6, the quotient ; AL = 08h = 8, the remainder Tips The microcontroller can only multiply unpacked decimal numbers. To multiply packed decimal numbers, unpack them first. To convert an unpacked decimal digit to its ASCII equivalent, use OR after AAM to add 30h (ASCII 0) to the digit. Related Instructions If you want to See Multiply two unsigned numbers MUL Instruction Set 4-7 AAS ASCII Adjust AL After Subtraction AAS Clocks Am186 Am188 Form Opcode Description AAS 3F ASCII-adjust AL after subtraction 7 7 What It Does AAS converts an 8-bit unsigned binary number that is the difference of two unpacked decimal (BCD) numbers to its unpacked decimal equivalent. Syntax AAS Description Use AAS only after a SUB or SBB instruction that leaves the byte result in AL. The lower nibbles of the operands of the SUB or SBB instruction must be in the range 0–9 (BCD). AAS adjusts AL so that it contains the correct decimal result. If the subtraction produced a decimal borrow, AAS decrements AH and sets CF and AF. If there is no decimal borrow, AAS clears CF and AF and leaves AH unchanged. AAS sets the top nibble of AL to 0. Operation It Performs if (((AL = AL & 0x0F) > 9) || (AF == 1)) /* AL is not yet decimal */ /* (note high nibble of AL is cleared either way */ { /* convert AL to decimal and unpack */ AL = (AL - 6) & 0x0F; AH = AH - 1; /* set carry flags */ CF = AF = 1; } else /* clear carry flags */ CF = AF = 0; Flag Settings After Instruction Processor Status Flags Register reserved 15 14 13 12 OF DF IF TF SF ZF AF ? – – – ? ? res 11 10 9 8 7 6 5 PF CF res ? res 4 3 2 1 0 ? = undefined; – = unchanged AF=1 if carry or borrow to low nibble CF=1 for carry or borrow to high-order bit AF=0 otherwise CF=0 otherwise 4-8 Instruction Set AAS AAS Examples This example subtracts one unpacked decimal number (the subtrahend) from another unpacked decimal number (the minuend). UMINUEND USUBTRAHEND DW DB 0103h 05h ; 13 unpacked BCD ; 5 unpacked BCD ; subtract unpacked decimal numbers MOV AX,UMINUEND ; AX = 0103h = 13 unpacked BCD SUB AL,USUBTRAHEND ; AX = 01FEh AAS ; AL = 08h = 8 unpacked BCD Tips To convert an unpacked decimal digit to its ASCII equivalent, use OR after AAS to add 30h (ASCII 0) to the digit. ADC, ADD, SBB, and SUB set AF when the result needs to be converted for decimal arithmetic. AAA, AAS, DAA, and DAS use AF to determine whether an adjustment is needed. This is the only use for AF. Related Instructions If you want to See Convert an 8-bit unsigned binary difference to its packed decimal equivalent Subtract a number and the value of CF from another number DAS SBB Subtract a number from another number SUB Instruction Set 4-9 ADC Add Numbers with Carry ADC Clocks Am186 Am188 Form Opcode Description ADC AL,imm8 14 ib Add immediate byte to AL with carry 3 3 ADC AX,imm16 15 iw Add immediate word to AX with carry 4 4 ADC r/m8,imm8 80 /2 ib Add immediate byte to r/m byte with carry 4/16 4/16 ADC r/m16,imm16 81 /2 iw Add immediate word to r/m word with carry 4/16 4/20 ADC r/m16,imm8 83 /2 ib Add sign-extended immediate byte to r/m word with carry 4/16 4/20 ADC r/m8,r8 10 /r Add byte register to r/m byte with carry 3/10 3/10 ADC r/m16,r16 11 /r Add word register to r/m word with carry 3/10 3/14 ADC r8,r/m8 12 /r Add r/m byte to byte register with carry 3/10 3/10 ADC r16,r/m16 13 /r Add r/m word to word register with carry 3/10 3/14 What It Does ADC adds two integers or unsigned numbers and the value of the Carry Flag (CF). Syntax ADC sum,addend Description ADC performs an integer addition of the two operands and the value of CF. ADC assigns the result to sum and sets CF as required. ADC is typically part of a multibyte or multiword addition operation. ADC sign-extends immediate-byte values to the appropriate size before adding to a word operand. Operation It Performs if (addend == imm8) if (size(sum) > 8) /* extend sign of addend */ if (addend < 0) addend = 0xFF00 | addend; else addend = 0x00FF & addend; /* add with carry */ sum = sum + addend + CF; 4-10 Instruction Set ADC ADC Flag Settings After Instruction OF DF Processor Status Flags Register – – – 10 9 8 reserved 15 14 13 12 11 IF TF SF ZF AF res 7 6 5 PF res 4 3 CF res 2 1 0 ? = undefined; – = unchanged OF=1 if result larger than destination operand OF=0 otherwise PF=1 if low byte of result has even number of set bits PF=0 otherwise SF=1 if result is 0 or positive SF=0 if result is negative ZF=1 if result equal to 0 ZF=0 if result not equal to 0 CF=1 for carry or borrow to high-order bit CF=0 otherwise AF=1 if carry or borrow to low nibble AF=0 otherwise Examples This example adds two 32-bit unsigned numbers. UADDEND1 UADDEND2 DD DD 592535620 3352720 ; 23516044h ; 00332890h ; 32-bit unsigned addition: UADDEND1 = UADDEND1 + UADDEND2 ; add left words (bytes and words reversed in memory) MOV AX,WORD PTR UADDEND2 ADD WORD PTR UADDEND1,AX ; add right words MOV AX,WORD PTR UADDEND2+2 ADC WORD PTR UADDEND1+2,AX Instruction Set ; UADDEND1 = 238488D4h ; = 595888340 4-11 ADC ADC This example adds two 3-byte packed decimal numbers. PADDEND1 PADDEND2 DB DB 00h,25h,86h,17h 00h,04h,21h,45h ; 258617 packed BCD ; 42145 packed BCD ; multibyte packed decimal addition: PADDEND1 = PADDEND1 + PADDEND2 ; add right bytes MOV AL,PADDEND1 + 3 ADD AL,PADDEND2 + 3 DAA MOV PADDEND1 + 3,AL ; add next bytes MOV AL,PADDEND1 + 2 ADC AL,PADDEND2 + 2 DAA MOV PADDEND1 + 2,AL ; add next bytes MOV AL,PADDEND1 + 1 ADC AL,PADDEND2 + 1 DAA MOV PADDEND1 + 1,AL ; if CF is 1, propagate carry into left byte JC ADD_CARRY JMP CONTINUE ADD_CARRY: MOV PADDEND1,1 CONTINUE: ... Tips To add two integers or two unsigned numbers that are both stored in memory, copy one of them to a register before using ADC. ADC requires both operands to be the same size. Before adding an 8-bit integer to a 16bit integer, convert the 8-bit integer to its 16-bit equivalent using CBW. To convert an 8-bit unsigned number to its 16-bit equivalent, use MOV to copy 0 to AH. To add numbers larger than 16 bits, use ADD to add the low words, and then use ADC to add each of the subsequently higher words. The microcontroller does not provide an instruction that performs decimal addition. To add decimal numbers, use ADD to perform binary addition, and then convert the result to decimal using AAA or DAA. ADC, ADD, SBB, and SUB set AF when the result needs to be converted for decimal arithmetic. AAA, AAS, DAA, and DAS use AF to determine whether an adjustment is needed. This is the only use for AF. 4-12 Instruction Set ADC ADC Related Instructions If you want to See Convert an 8-bit unsigned binary sum to its unpacked decimal equivalent Add two numbers AAA ADD Convert an 8-bit integer to its 16-bit equivalent Convert an 8-bit unsigned binary sum to its packed decimal equivalent CBW DAA Change the sign of an integer NEG Instruction Set 4-13 ADD Add Numbers ADD Clocks Am186 Am188 Form Opcode Description ADD AL,imm8 04 ib Add immediate byte to AL 3 3 ADD AX,imm16 05 iw Add immediate word to AX 4 4 ADD r/m8,imm8 80 /0 ib Add immediate byte to r/m byte 4/16 4/16 ADD r/m16,imm16 81 /0 iw Add immediate word to r/m word 4/16 4/20 ADD r/m16,imm8 83 /0 ib Add sign-extended immediate byte to r/m word 4/16 4/20 ADD r/m8,r8 00 /r Add byte register to r/m byte 3/10 3/10 ADD r/m16,r16 01 /r Add word register to r/m word 3/10 3/14 ADD r8,r/m8 02 /r Add r/m byte to byte register 3/10 3/10 ADD r16,r/m16 03 /r Add r/m word to word register 3/10 3/14 What It Does ADD adds two integers or unsigned numbers. Syntax ADD sum,addend Description ADD performs an integer addition of the two operands. ADD assigns the result to sum and sets the flags accordingly. ADD sign-extends immediate byte values to the appropriate size before adding to a word operand. Operation It Performs if (addend == imm8) if (size(sum) > 8) /* extend sign of addend */ if (addend < 0) addend = 0xFF00 | addend; else addend = 0x00FF & addend; /* add */ sum = sum + addend; 4-14 Instruction Set ADD ADD Flag Settings After Instruction OF DF Processor Status Flags Register – – – 10 9 8 reserved 15 14 13 12 11 IF TF SF ZF AF res 7 6 5 PF res 4 3 CF res 2 1 0 ? = undefined; – = unchanged OF=1 if result larger than destination operand OF=0 otherwise CF=1 for carry or borrow to high-order bit CF=0 otherwise PF=1 if low byte of result has even number of set bits PF=0 otherwise SF=1 if result is 0 or positive SF=0 if result is negative AF=1 if carry or borrow to low nibble AF=0 otherwise ZF=1 if result equal to 0 ZF=0 if result not equal to 0 Examples This example adds two 16-bit integers. SADDEND1 SADDEND2 DW DW -6360 723 ; add signed numbers MOV AX,SADDEND2 ADD SADDEND1,AX ; E6ECh ; 02D3h ; AX = 723 ; SADDEND1 = -5637 This example adds two 32-bit unsigned numbers. UADDEND1 UADDEND2 DD DD 592535620 3352720 ; 23516044h ; 00332890h ; 32-bit unsigned addition: UADDEND1 = UADDEND1 + UADDEND2 ; add left words (bytes and words reversed in memory) MOV AX,WORD PTR UADDEND2 ; AX=2890h ADD WORD PTR UADDEND1,AX ; UADEND1=2351h::(2890h+6044h) =235188D4h ; add right words MOV AX,WORD PTR UADDEND2+2 ; AX=0033h ADC WORD PTR UADDEND1+2,AX ; UADDEND1=(2351h+0033h)::88D4h ; =238488D4h ; =595888340 Tips To add two integers or two unsigned numbers that are both stored in memory, copy one of them to a register before using ADD. ADD requires both operands to be the same size. Before adding an 8-bit integer to a 16bit integer, convert the 8-bit integer to its 16-bit equivalent using CBW. To convert an 8-bit unsigned number to its 16-bit equivalent, use MOV to copy 0 to AH. To add numbers larger than 16 bits, use ADD to add the low words, and then use ADC to add each of the subsequently higher words. Use INC instead of ADD within a loop when you want to increase a value by 1 each time the loop is executed. Instruction Set 4-15 ADD ADD The microcontroller does not provide an instruction that performs decimal addition. To add decimal numbers, use ADD to perform binary addition, and then convert the result to decimal using AAA or DAA. ADC, ADD, SBB, and SUB set AF when the result needs to be converted for decimal arithmetic. AAA, AAS, DAA, and DAS use AF to determine whether an adjustment is needed. This is the only use for AF. Related Instructions 4-16 If you want to See Convert an 8-bit unsigned binary sum to its unpacked decimal equivalent AAA Add two numbers and the value of CF Convert an 8-bit integer to its 16-bit equivalent ADC CBW Convert an 8-bit unsigned binary sum to its packed decimal equivalent Add 1 to a number DAA INC Change the sign of an integer NEG Instruction Set AND Logical AND AND Clocks Am186 Am188 Form Opcode Description AND AL,imm8 24 ib AND immediate byte with AL 3 3 AND AX,imm16 25 iw AND immediate word with AX 4 4 AND r/m8,imm8 80 /4 ib AND immediate byte with r/m byte 4/16 4/16 AND r/m16,imm16 81 /4 iw AND immediate word with r/m word 4/16 4/20 AND r/m16,imm8 83 /4 ib AND sign-extended immediate byte with r/m word 4/16 4/20 AND r/m8,r8 20 /r AND byte register with r/m byte 3/10 3/10 AND r/m16,r16 21 /r AND word register with r/m word 3/10 3/14 AND r8,r/m8 22 /r AND r/m byte with byte register 3/10 3/10 AND r16,r/m16 23 /r AND r/m word with word register 3/10 3/14 What It Does AND clears particular bits of a component to 0 according to a mask. Syntax AND component,mask Description AND computes the logical AND of the two operands. If corresponding bits of the operands are 1, the resulting bit is 1. If either bit or both are 0, the result is 0. The answer replaces component. Operation It Performs /* AND component with mask */ component = component & mask; /* clear overflow and carry flags */ OF = CF = 0; Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF 0 – – – 11 10 9 8 AF PF res ? res 7 6 5 4 3 CF res 0 2 1 0 ? = undefined; – = unchanged SF=1 if result is 0 or positive SF=0 if result is negative ZF=1 if result equal to 0 ZF=0 if result not equal to 0 PF=1 if low byte of result has even number of set bits PF=0 otherwise Instruction Set 4-17 AND AND Examples This example converts an ASCII number to its unpacked decimal equivalent. BCD_MASK ASCII_NUM EQU DB 0Fh 36h ; convert ASCII number to decimal MOV AL,ASCII_NUM AND AL,BCD_MASK ; ASCII-to-decimal mask ; ASCII ’6’ ; AL = 36h = ASCII ”6” ; AL = 06h = decimal 6 This example extracts the middle byte of a word so it can be used by another instruction. SETTINGS DW 1234h ; extract middle byte of AX and place in AH MOV AX,SETTINGS ; AX = 1234h AND AX,0FF0h ; mask middle byte: AX = 0230h SHL AX,4 ; shift middle byte into AH: AX = 2300h Tips To convert an ASCII number (30–39h) to its unpacked decimal equivalent, use AND with a mask of 0Fh to clear the bits in the high nibble of the byte. Related Instructions 4-18 If you want to See Toggle all bits of a component NOT Set particular bits of a component to 1 Toggle particular bits of a component OR XOR Instruction Set BOUND*Check Array Index Against Bounds BOUND Form Opcode Description Clocks Am186 Am188 BOUND r16,m16&16 62 /r Check to see if word register is within bounds 33–35 33–35 What It Does BOUND determines whether an integer falls between two boundaries. Syntax BOUND index,bounds Description BOUND ensures that a signed array index is within the limits specified by a block of memory between an upper and lower bound. The first operand (from the specified register) must be greater than or equal to the lower bound value, but not greater than the upper bound. The lower bound value is stored at the address specified by the second operand. The upper bound value is stored at a consecutive higher memory address (+2). If the first operand is out of the specified bounds, BOUND issues an Interrupt 5 Request. The saved IP points to the BOUND instruction. Operation It Performs if ((index < [bounds]) || (index > [bounds + 2])) /* integer is outside of boundaries */ interrupt(5); Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged * – This instruction was not available on the original 8086/8088 systems. Instruction Set 4-19 BOUND BOUND Examples This example compares a word in a table to the value in AX. Before the comparison, BOUND checks to see if the table index is within the range of the table. If it is not, the microcontroller generates Interrupt 5. BOUNDARIES TABLE DW DW 0,256 4096 DUP (?) ; search table for value in AX ; fill table with values and load AX with search key CALL FILL_TABLE CALL GET_KEY ; load SI with index ... ; check index before comparison BOUND SI,BOUNDARIES ; if out of bounds, call interrupt 5 CMP TABLE[SI],AX ; compare components ... Tips Use BOUND to check a signed index value to see if it falls within the range of an array. Related Instructions 4-20 If you want to See Compare two components using subtraction and set the flags accordingly CMP Generate an interrupt INT Instruction Set CALL Call Procedure CALL Clocks Am186 Am188 Form Opcode Description CALL rel16 E8 cw Call near, displacement relative to next instruction CALL r/m16 FF /2 Call near, register indirect/memory indirect CALL ptr16:16 9A cd CALL m16:16 FF /3 15 19 13/19 17/27 Call far to full address given 23 31 Call far to address at m16:16 word 38 54 What It Does CALL calls a procedure. Syntax CALL procedure Description CALL suspends execution of the current instruction sequence, saves the segment (if necessary) and offset addresses of the next instruction, and begins executing the procedure named by the operand. A return at the end of the called procedure exits the procedure and starts execution at the instruction following the CALL instruction. CALL rel16 and CALL r/m16 are near calls. They use the current Code Segment register value. Near calls push the offset of the next instruction (IP) onto the stack. The near RET instruction in the procedure pops the instruction offset when it returns control. n Near direct calls (relative): CALL rel16 adds a signed offset to the address of the next instruction to determine the destination. CALL stores the result in the IP register. n Near indirect calls (absolute): CALL r/m16 specifies a register or memory location from which the 16-bit absolute segment offset is fetched. CALL stores the result in the IP register. CALL ptr16:16 and CALL m16:16 are far calls. They use a long pointer to the called procedure. The long pointer provides 16 bits for the CS register and 16 for the IP register. Far calls push both the CS and IP registers as a return address. A far return must be used to pop both CS and IP from the stack. n Far direct calls: CALL ptr16:16 uses a 4-byte operand as a long pointer to the called procedure. n Far indirect calls: CALL m16:16 fetches the long pointer from the memory location specified (indirection). A CALL-indirect-through-memory, using the stack pointer (SP) as a base register, references memory before the call. The base is the value of SP before the instruction executes. Instruction Set 4-21 CALL CALL Operation It Performs /* save return offset */ push(IP); if (procedure == rel16) /* near direct call */ IP = IP + rel16; if (procedure == r/m16) /* near indirect call */ IP = [r/m16]; if ((procedure == ptr16:16) || (procedure == m16:16)) /* far call */ { /* save return segment */ push(CS); if (procedure == ptr16:16) /* far direct call */ CS:IP = ptr16:16; else /* far indirect call */ CS:IP = [m16:16]; } Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Examples This example calls a procedure whose address is stored in a doubleword in memory. PROC_ADDR DD ? ; full address of current procedure ; store address of current procedure in PROC_ADDR ... LDS SI,PROC_ADDR ; load segment of procedure into DS ; and offset of procedure into SI ; call procedure at address stored in doubleword in memory CALL DWORD PTR [SI] 4-22 Instruction Set CALL CALL Tips The assembler generates the correct call (near or far) based on the declaration of the called procedure. Related Instructions If you want to See Stop executing the current sequence of instructions and begin executing another JMP End a procedure and return to the calling procedure RET Instruction Set 4-23 CBW Convert Byte Integer to Word CBW Clocks Am186 Am188 Form Opcode Description CBW 98 Put signed extension of AL in AX 2 2 What It Does CBW converts an 8-bit integer to a sign-extended 16-bit integer. Syntax CBW Description CBW converts the signed byte in the AL register to a signed word in the AX register by extending the most significant bit of the AL register (the sign bit) into all of the bits of the AH register. Operation It Performs /* extend sign of AL to AX */ if (AL < 0) AH = 0xFF; else AH = 0x00; Flag Settings After Instruction OF DF Processor Status Flags Register 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 reserved 5 4 3 2 1 0 ? = undefined; – = unchanged Examples This example converts an 8-bit integer to its 16-bit equivalent before adding it to another 16-bit integer. SADDEND1 SADDEND2 DB DW -106 25000 ; 96h ; 61A8h ; add word integer to byte integer MOV AL,SADDEND1 ; AL = 96h = -106 CBW ; AX = FF96h = -106 ADD AX,SADDEND2 ; AX = 613Eh = 24894 4-24 Instruction Set CBW CBW This example converts an 8-bit integer to its 16-bit equivalent before dividing it by an 8-bit integer. SDIVIDEND SDIVISOR DB DB 101 -3 ; divide byte integers MOV AL,SDIVIDEND CBW IDIV SDIVISOR ; 65h ; FDh ; ; ; , AL AX AL AH = = = = 65h = 0065h DFh = 02h = 101 = 101 -33, the quotient 2, the remainder Tips To convert an 8-bit unsigned number in AL to its 16-bit equivalent, use MOV to copy 0 to AH. Related Instructions If you want to See Add two numbers with the value of CF Add two numbers ADC ADD Convert a 16-bit integer to its 32-bit equivalent Divide an integer by another integer CWD IDIV Subtract a number and the value of CF from another number SBB Subtract a number from another number SUB Instruction Set 4-25 CLC Clear Carry Flag CLC Clocks Am186 Am188 Form Opcode Description CLC F8 Clear Carry Flag 2 2 What It Does CLC clears the Carry Flag (CF) to 0. Syntax CLC Description CLC clears CF. Operation It Performs /* clear carry flag */ CF = 0; Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res 0 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Examples This example rotates the bits of a byte to the left, making sure that the high bit remains 0. ; rotate byte, maintaining 0 in high bit MOV AL,01101011b ; AL = 01101011b CLC ; CF = 0 RCR AL,1 ; AL = 00110101b, CF = 1 4-26 Instruction Set CLC CLC This example scans a string in memory until it finds a character or until the entire string is scanned. The microcontroller scans the bytes, one by one, from first to last. If the string contains the character, the microcontroller sets the Carry Flag (CF) to 1; otherwise, it clears CF to 0. STRING NULL DB EQU 10 DUP (?) 0 ; notify assembler that DS and ES specify ; the same segment of memory ASSUME DS:DATASEG, ES:DATASEG ; set up segment registers MOV AX,DATASEG MOV DS,AX MOV ES,AX with same segment ; copy data segment to AX ; copy AX to DS ; copy AX to ES ; initialize and use string ... ; set up registers and flags MOV AL,NULL ; LEA DI,STRING ; MOV CX,LENGTH STRING ; CLD ; REPNE copy character to AL load offset (segment = ES) set up counter process string low to high ; scan string for character SCASB ; if string contains character JE FOUND ; else JMP NOT_FOUND FOUND: STC JMP NOT_FOUND: CLC ; indicate found CONTINUE ; indicate not found CONTINUE: ... Instruction Set 4-27 CLC CLC Tips You can use CF to indicate the outcome of a procedure, such as when searching a string for a character. For instance, if the character is found, you can use STC to set CF to 1; if the character is not found, you can use CLC to clear CF to 0. Then, subsequent instructions that do not affect CF can use its value to determine the appropriate course of action. To rotate a 0 into a component, use CLC to clear CF to 0 before using RCL or RCR. Related Instructions 4-28 If you want to See Toggle the value of CF CMC Rotate the bits of a component and CF to the left RCL Rotate the bits of a component and CF to the right Set CF to 1 RCR STC Instruction Set CLD Clear Direction Flag CLD Clocks Am186 Am188 Form Opcode Description CLD FC Clear Direction Flag so the Source Index (SI) and/or the Destination Index (DI) registers will increment during string instructions 2 2 What It Does CLD clears the Direction Flag (DF) to 0, causing subsequent repeated string instructions to process the components of a string from a lower address to a higher address. Syntax CLD Description CLD clears DF, causing subsequent string operations to increment the index registers on which they operate: SI and/or DI. Operation It Performs /* process string components from lower to higher addresses */ DF = 0; Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – 0 – – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Examples This example fills a string in memory with a character. Because the Direction Flag (DF) is cleared to 0 using CLD, the bytes are filled, one by one, from first to last. STRING POUND DB DB 128 DUP (?) ’#’ ; 2Ah ; fill string with character ; set up registers and flags MOV AX,SEG STRING MOV ES,AX MOV AL,POUND LEA DI,STRING MOV CX,LENGTH STRING CLD REP ; ; ; ; copy character to AL load offset (segment = ES) set up counter process string going forward ; fill string STOSB Instruction Set 4-29 CLD CLD This example copies one string of 16-bit integers in memory to another string in the same segment. Because the Direction Flag (DF) is cleared to 0 using CLD, the microcontroller copies the words, one by one, from first to last. ; defined in SEG_1 segment SOURCE DW 350,-4821,-276,449,10578 DEST DW 5 DUP (?) ; direct assembler that DS and ES point to ; the same segment of memory ASSUME DS:SEG_1, ES:SEG_1 ; set up DS and ES with same segment address MOV AX,SEG_1 ; copy data segment to AX MOV DS,AX ; copy AX to DS MOV ES,AX ; copy AX to ES ; set up registers and flags LEA SI,SOURCE ; load source offset (segment = DS) LEA DI,DEST ; load dest. offset (segment = ES) MOV CX,5 ; set up counter CLD ; process string low to high REP ; copy source string to destination string MOVSW Tips Before using one of the string instructions (CMPS, INS, LODS, MOVS, OUTS, SCAS, or STOS), always set up CX with the length of the string, and use CLD (forward) or STD (backward) to establish the direction for string processing. The string instructions always advance SI and/or DI, regardless of the use of the REP prefix. Be sure to set or clear DF before any string instruction. Related Instructions 4-30 If you want to See Compare a component in one string with a component in another string Copy a component from a port in I/O memory to a string in main memory CMPS INS Copy a component from a string in memory to a register LODS Copy a component from one string in memory to another string in memory Copy a component from a string in main memory to a port in I/O memory MOVS OUTS Compare a string component located in memory to a register Process string components from higher to lower addresses SCAS STD Copy a component from a register to a string in memory STOS Instruction Set CLI Clear Interrupt-Enable Flag CLI Clocks Am186 Am188 Form Opcode Description CLI FA Clear Interrupt-Enable Flag (IF) 2 2 What It Does CLI clears the Interrupt-Enable Flag (IF), disabling all maskable interrupts. Syntax CLI Description CLI clears IF. Maskable external interrupts are not recognized at the end of the CLI instruction—or from that point on—until IF is set. Operation It Performs /* disable maskable interrupts */ IF = 0; Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – 0 – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Instruction Set 4-31 CLI CLI Examples This example of an interrupt-service routine: enables interrupts so that interrupt nesting can occur, resets a device, disables interrupts until the interrupted procedure is resumed, and then clears the in-service bits in the In-Service (INSERV) register by writing to the EndOf-Interrupt (EOI) register. ; the microcontroller pushes the flags onto ; the stack before executing this routine ; enable interrupt nesting during routine ISR1 PROC FAR PUSHA STI ; save general registers ; enable unmasked maskable interrupts mRESET_DEVICE1 CLI ; perform operation (macro) ; disable maskable interrupts until IRET ; reset MOV MOV OUT in-service bits by writing to EOI register DX,INT_EOI_ADDR ; address of EOI register AX,8000h ; non-specific EOI DX,AX ; write to EOI register POPA IRET ISR1 ; restore general registers ENDP ; the microcontroller pops the flags from the stack ; before returning to the interrupted procedure Tips When the Interrupt-Enable Flag (IF) is cleared to 0 so that all maskable interrupts are disabled, you can still use INT to generate an interrupt, even if it is masked by its interrupt control register. Software interrupts and traps, and nonmaskable interrupts are not affected by the IF flag. The IRET instruction restores the value of the Processor Status Flags register from the value pushed onto the stack when the interrupt was taken. Modifying the Processor Status Flags register via the STI, CLI or other instruction will not affect the flags after the IRET. If you disable maskable interrupts using CLI, the microcontroller does not recognize maskable interrupt requests until the instruction that follows STI is executed. After using CLI to disable maskable interrupts, use STI to enable them as soon as possible to reduce the possibility of missing maskable interrupt requests. Related Instructions If you want to See Enable maskable interrupts that are not masked by their interrupt control registers STI 4-32 Instruction Set CMC Complement Carry Flag CMC Clocks Am186 Am188 Form Opcode Description CMC F5 Complement Carry Flag 2 2 What It Does CMC toggles the value of the Carry Flag (CF). Syntax CMC Description CMC reverses the setting of CF. Operation It Performs /* toggle value of carry flag */ CF = ~ CF; Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged CF contains the complement of its original value Related Instructions If you want to See Clear the value of CF to 0 CLC Rotate the bits of a component and CF to the left Rotate the bits of a component and CF to the right RCL RCR Set the value of CF to 1 STC Instruction Set 4-33 CMP Compare Components CMP Clocks Am186 Am188 Form Opcode Description CMP AL,imm8 3C ib Compare immediate byte to AL 3 3 CMP AX,imm16 3D iw Compare immediate word to AX 4 4 CMP r/m8,imm8 80 /7 ib Compare immediate byte to r/m byte 3/10 3/10 CMP r/m16,imm16 81 /7 iw Compare immediate word to r/m word 3/10 3/14 CMP r/m16,imm8 83 /7 ib Compare sign-extended immediate byte to r/m word 3/10 3/14 CMP r/m8,r8 38 /r Compare byte register to r/m byte 3/10 3/10 CMP r/m16,r16 39 /r Compare word register to r/m word 3/10 3/14 CMP r8,r/m8 3A /r Compare r/m byte to byte register 3/10 3/10 CMP r16,r/m16 3B /r Compare r/m word to word register 3/10 3/14 What It Does CMP compares two components using subtraction and sets the flags accordingly. Syntax CMP value1,value2 Description CMP subtracts the second operand from the first, but does not store the result. CMP only changes the flag settings. The CMP instruction is typically used in conjunction with conditional jumps. If an operand greater than one byte is compared to an immediate byte, the byte value is first sign-extended. Operation It Performs if (value2 == imm8) if (size(value1) > 8) /* extend sign of value2 */ if (value2 < 0) value2 = 0xFF00 | value2; else value2 = 0x00FF & value2; /* compare values */ temp = value1 - value2; /* don’t store result, but set appropriate flags */ 4-34 Instruction Set CMP CMP Flag Settings After Instruction OF DF Processor Status Flags Register – – – 10 9 8 reserved 15 14 13 12 11 IF TF SF ZF AF res 7 6 5 PF res 4 3 CF res 2 1 0 ? = undefined; – = unchanged OF=1 if result larger than destination operand OF=0 otherwise CF=1 for carry or borrow to high-order bit CF=0 otherwise PF=1 if low byte of result has even number of set bits PF=0 otherwise SF=1 if result is 0 or positive SF=0 if result is negative AF=1 if carry or borrow to low nibble AF=0 otherwise ZF=1 if result equal to 0 ZF=0 if result not equal to 0 Examples This example waits for a character from the serial port. DEC, JCXZ, and JMP implement a construct equivalent to the C-language do-while loop. CMP and JNE implement an if statement within the loop. ; loop for a maximum number of times or until a ; serial-port character is ready MOV CX,100h LOOP_TOP: CHAR_READY CMP AH,0 JNE GOT_CHAR DEC CX JCXZ NO_CHAR JMP LOOP_TOP ; set up counter ; ; ; ; ; ; read character into AH (macro) is a character ready? if so, then jump out with character subtract 1 from counter if CX is 0, jump out without character if not, jump to top of loop GOT_CHAR: ... NO_CHAR: ... Tips Don’t compare signed values with unsigned values. Compare either two integers or two unsigned numbers. Related Instructions If you want to See Determine whether particular bits of a component are set to 1 TEST Instruction Set 4-35 CMPS Compare String Components CMPSB Compare String Bytes CMPSW Compare String Words CMPS Clocks Am186 Am188 Form Opcode Description CMPS m8,m8 A6 Compare byte ES:[DI] to byte segment:[SI] 22 22 CMPS m16,m16 A7 Compare word ES:[DI] to word segment:[SI] 22 26 CMPSB A6 Compare byte ES:[DI] to byte DS:[SI] 22 22 CMPSW A7 Compare word ES:[DI] to word DS:[SI] 22 26 What It Does CMPS compares a component in one string to a component in another string. Syntax CMPS source,destination CMPSB CMPSW To override the default source segment (DS) and to have the assembler type-check your operands, use this form. In this form, source is segment:[SI]. The assembler uses the segment in DS unless you specify a different segment register as part of the source string component. The assembler uses the definitions of the string components to determine their sizes. To compare a byte within a string located in the destination segment specified in ES to a byte within a string located in the source segment specified in DS, use this form. Regardless of the form of CMPS you use, destination is always ES:[DI]. Before using any form of CMPS, make sure that: ES contains the segment of the destination string, DI contains the offset of the destination string, and SI contains the offset of the source string. To compare a word within a string located in the destination segment specified in ES to a word within a string located in the source segment specified in DS, use this form. Description CMPS compares the byte or word pointed to by the SI register with the byte or word pointed to by the DI register. You must preload the registers before executing CMPS. CMPS subtracts the DI indexed operand from the SI indexed operand. No result is stored; only the flags reflect the change. The operand size determines whether bytes or words are compared. The first operand (SI) uses the DS register unless a segment override byte is present. The second operand (DI) must be addressable from the ES register; no segment override is possible. After the comparison, both the source-index register and the destination-index register are automatically advanced. If DF is 0, the registers increment according to the operand size (byte=1; word=2); if DF is 1, the registers decrement. CMPSB and CMPSW are synonymous with the byte and word CMPS instructions, respectively. 4-36 Instruction Set CMPS CMPS Operation It Performs if (size(destination) == 8) /* compare bytes */ { temp = DS:[SI] - ES:[DI]; if (DF == 0) increment = 1; else increment = -1; } /* compare */ /* forward */ /* backward */ if (size(destination) == 16) /* compare words */ { temp = DS:[SI] - ES:[DI]; if (DF == 0) increment = 2; else increment = -2; } /* forward */ /* backward */ /* point to next string component */ SI = SI + increment; DI = DI + increment; Flag Settings After Instruction OF DF Processor Status Flags Register – – – 10 9 8 reserved 15 14 13 12 11 IF TF SF ZF AF res 7 6 5 PF res 4 3 CF res 2 1 0 ? = undefined; – = unchanged OF=1 if result larger than destination operand OF=0 otherwise SF=1 if result is 0 or positive SF=0 if result is negative ZF=1 if result equal to 0 ZF=0 if result not equal to 0 CF=1 for carry or borrow to high-order bit CF=0 otherwise PF=1 if low byte of result has even number of set bits PF=0 otherwise AF=1 if carry or borrow to low nibble AF=0 otherwise Instruction Set 4-37 CMPS CMPS Examples This example compares for equality one string of nonzero words stored in the segment specified in ES to another string of nonzero words located in the same segment. The microcontroller compares the words, one by one, from first to last, unless any two words being compared don’t match. If both strings are the same, the microcontroller loads 0 into AX; otherwise, it loads the word that was different in the second string into AX. ; defined in SEG_E segment STRING1 DW 64 DUP (?) STRING2 DW LENGTH STRING1 DUP (?) ; compare strings for equality ; notify assembler: DS and ES point to ; different segments of memory ASSUME DS:SEG_D, ES:SEG_E ; set up DS and ES with different segment addresses MOV AX,SEG_D ; load one segment into DS MOV DS,AX ; DS points to SEG_D MOV AX,SEG_E ; load another segment into ES MOV ES,AX ; ES points to SEG_E ; initialize and use strings ... ; set up registers and flags LEA SI,ES:STRING1 ; load source offset (segment = ES) LEA DI,STRING2 ; load dest. offset (segment = ES) MOV CX,LENGTH STRING1 ; set up counter CLD ; process string low to high REPE ; compare strings for equality using segment override ; for source CMPS ES:STRING1,STRING2 ; if both strings are the same, then jump JE SAME ; else, load unequal word into AX MOV AX,STRING2[DI] JMP CONTINUE SAME: ; indicate both strings are the same MOV AX,0 CONTINUE: ... 4-38 Instruction Set CMPS CMPS Tips Before using CMPS, always set up CX with the length of the string, and use CLD (forward) or STD (backward) to establish the direction for string processing. To determine whether one string is the same as another, use the REPE (or REPZ) prefix to execute CMPS repeatedly. If all the corresponding components match, ZF is set to 1. To determine whether one string is different from another, use the REPNE (or REPNZ) prefix to execute CMPS repeatedly. If no corresponding components match, ZF is cleared to 0. The string instructions always advance SI and/or DI, regardless of the use of the REP prefix. Be sure to set or clear DF before any string instruction. Related Instructions If you want to See Process string components from lower to higher addresses CLD Repeat one string comparison instruction while the components are the same REPE Repeat one string comparison instruction while the components are not the same REPNE Compare a component in a string to a register Process string components from higher to lower addresses Instruction Set SCAS STD 4-39 CWD Convert Word Integer to Doubleword CWD Clocks Am186 Am188 Form Opcode Description CWD 99 Put signed extension of AX in DX::AX 4 4 What It Does CWD converts a 16-bit integer to a sign-extended 32-bit integer. Syntax CWD Description CWD converts the signed word in the AX register to a signed doubleword in the DX::AX register pair by extending the most significant bit of the AX register into all the bits of the DX register. Operation It Performs /* extend sign of AX into DX */ if (AX < 0) DX = 0xFFFF; else DX = 0x0000; Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 ? = undefined; – = unchanged 5 4 3 2 1 0 ? = unknown; – = unchanged Examples This example divides one 16-bit integer by another 16-bit integer. SDIVIDEND SDIVISOR DW DW 5800 -45 ; divide word integers MOV AX,SDIVIDEND CWD IDIV SDIVISOR 4-40 ; 16A8h ; FFD3h ; ; ; ; AX = 16A8h = 5800 DX::AX = 000016A8h = 5800 AX = FF80h = -128, the quotient DX = 0028h = -40, the remainder Instruction Set CWD CWD This example divides one 16-bit integer by another 16-bit integer. SDIVIDEND SDIVISOR DW DW -1675 200 ; divide word integers MOV AX,SDIVIDEND CWD IDIV SDIVISOR ; F975h ; 00C8h ; ; ; ; AX = F975h = -1675 DX::AX = FFFFF975h = -1675 AX = FFF8h = -8, the quotient DX = FFB5h = -75, the remainder Tips If you want to divide a 16-bit integer (the dividend) by another 16-bit integer (the divisor): use MOV to copy the dividend to AX, use CWD to convert the dividend into its 32-bit equivalent, and then use IDIV to perform the division. Related Instructions If you want to See Convert an 8-bit integer to its 16-bit equivalent CBW Divide an integer by another integer IDIV Instruction Set 4-41 DAA Decimal Adjust AL After Addition DAA Clocks Am186 Am188 Form Opcode Description DAA 27 Decimal-adjust AL after addition 4 4 What It Does DAA converts an 8-bit unsigned binary number that is the sum of two single-byte packed decimal (BCD) numbers to its packed decimal equivalent. Syntax DAA Description Execute DAA only after executing an ADD or ADC instruction that leaves a two-BCD-digit byte result in the AL register. The ADD or ADC operands should consist of two packed BCD digits. DAA adjusts the AL register to contain the correct two-digit packed decimal result. Operation It Performs if (((AL & 0x0F) > 9) || (AF == 1)) /* low nibble of AL is not yet in BCD format */ { /* convert low nibble of AL to decimal */ AL = AL + 6; /* set auxiliary (decimal) carry flag */ AF = 1; } else /* clear auxiliary (decimal) carry flag */ AF = 0; if ((AL > 0x9F) || (CF == 1)) /* high nibble of AL is not yet in BCD format */ { /* convert high nibble of AL to decimal */ AL = AL + 0x60; /* set carry flag */ CF = 1; } else /* clear carry flag */ CF = 0; 4-42 Instruction Set DAA DAA Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF ? – – – 11 10 9 8 AF res 7 6 5 PF res 4 3 CF res 2 1 0 ? = undefined; – = unchanged CF=1 for carry or borrow to high-order bit CF=0 otherwise SF=1 if result is 0 or positive SF=0 if result is negative PF=1 if low byte of result has even number of set bits PF=0 otherwise ZF=1 if result equal to 0 ZF=0 if result not equal to 0 AF=1 if carry or borrow to low nibble AF=0 otherwise Examples This example adds two 3-byte packed decimal numbers. PADDEND1 PADDEND2 DB DB 00h,24h,17h,08h 00h,19h,30h,11h ; 241708 packed BCD ; 193011 packed BCD ; multibyte packed decimal addition: PADDEND1 = PADDEND1 + PADDEND2 ; add right bytes MOV AL,PADDEND1 + 3 ADD AL,PADDEND2 + 3 DAA MOV PADDEND1 + 3,AL ; add next bytes MOV AL,PADDEND1 + 2 ADC AL,PADDEND2 + 2 DAA MOV PADDEND1 + 2,AL ; add next bytes MOV AL,PADDEND1 + 1 ADC AL,PADDEND2 + 1 DAA MOV PADDEND1 + 1,AL ; if CF is 1, propagate carry into left byte JC ADD_CARRY JMP CONTINUE ADD_CARRY: MOV PADDEND1,1 CONTINUE: ... Instruction Set 4-43 DAA DAA Tips ADC, ADD, SBB, and SUB set AF when the result needs to be converted for decimal arithmetic. AAA, AAS, DAA, and DAS use AF to determine whether an adjustment is needed. This is the only use for AF. Related Instructions 4-44 If you want to See Convert an 8-bit unsigned binary sum to its unpacked decimal equivalent AAA Add two numbers and the value of CF Add two numbers ADC ADD Convert an 8-bit unsigned binary difference to its packed decimal equivalent DAS Instruction Set DAS Decimal Adjust AL After Subtraction DAS Clocks Am186 Am188 Form Opcode Description DAS 2F Decimal-adjust AL after subtraction 4 4 What It Does DAS converts an 8-bit unsigned binary number that is the difference of two single-byte packed decimal (BCD) numbers to its packed decimal equivalent. Syntax DAS Description Execute DAS only after a SUB or SBB instruction that leaves a two-BCD-digit byte result in the AL register. The SUB or SBB operands should consist of two packed BCD digits. DAS adjusts the AL register to contain the correct packed two-digit decimal result. Operation It Performs if (((AL & 0x0F) > 9) || (AF == 1)) /* low nibble of AL is not yet in BCD format */ { /* convert low nibble of AL to decimal */ AL = AL - 6; /* set auxiliary (decimal) carry flag */ AF = 1; } else /* clear auxiliary (decimal) carry flag */ AF = 0; if ((AL > 0x9F) || (CF == 1)) /* high nibble of AL is not yet in BCD format */ { /* convert high nibble of AL to decimal */ AL = AL - 0x60; /* set carry flag */ CF = 1; } else /* clear carry flag */ CF = 0; Instruction Set 4-45 DAS DAS Flag Settings After Instruction OF DF Processor Status Flags Register ? – – – 11 10 9 8 reserved 15 14 13 12 IF TF SF ZF AF res 7 6 5 PF res 4 3 CF res 2 1 0 ? = undefined; – = unchanged CF=1 for carry or borrow to high-order bit CF=0 otherwise SF=1 if result is 0 or positive SF=0 if result is negative PF=1 if low byte of result has even number of set bits PF=0 otherwise ZF=1 if result equal to 0 ZF=0 if result not equal to 0 AF=1 if carry or borrow to low nibble AF=0 otherwise Examples This example subtracts two 3-byte packed decimal numbers. PBCD1 PBCD2 DB DB 24h,17h,08h 19h,30h,11h ; 241708 packed BCD ; 193011 packed BCD ; multibyte packed decimal subtraction: PBCD1 = PBCD1 - PBCD2 ; subtract right bytes MOV AL,PBCD1 + 2 SBB AL,PBCD2 + 2 DAS MOV PBCD1 + 2,AL ; subtract next bytes MOV AL,PBCD1 + 1 SBB AL,PBCD2 + 1 DAS MOV PBCD1 + 1,AL ; subtract left bytes MOV AL,PBCD1 SBB AL,PBCD2 DAS MOV PBCD1,AL ; if CF is 1, the last subtraction generated a borrow JC INVALID ; result is an error JMP CONTINUE INVALID: ... CONTINUE: ... 4-46 Instruction Set DAS DAS Tips ADC, ADD, SBB, and SUB set AF when the result needs to be converted for decimal arithmetic. AAA, AAS, DAA, and DAS use AF to determine whether an adjustment is needed. This is the only use for AF. Related Instructions If you want to See Convert an 8-bit unsigned binary difference to its unpacked decimal equivalent AAS Convert an 8-bit unsigned binary sum to its packed decimal equivalent Subtract a number and the value of CF from another number DAA SBB Subtract a number from another number SUB Instruction Set 4-47 DEC Decrement Number by One DEC Form Opcode Description Clocks Am186 Am188 DEC r/m8 FE /1 Subtract 1 from r/m byte 3/15 3/15 DEC r/m16 FF /1 Subtract 1 from r/m word 3/15 3/19 DEC r16 48+ rw Subtract 1 from word register 3 3 What It Does DEC subtracts 1 from an integer or an unsigned number. Syntax DEC minuend Description DEC subtracts 1 from the operand. Operation It Performs /* decrement minuend */ minuend = minuend - 1; Flag Settings After Instruction OF DF Processor Status Flags Register – – – 10 9 8 reserved 15 14 13 12 11 IF TF SF ZF AF res 7 6 5 PF res 4 3 CF res – 2 1 0 ? = undefined; – = unchanged OF=1 if result larger than destination operand OF=0 otherwise PF=1 if low byte of result has even number of set bits PF=0 otherwise SF=1 if result is 0 or positive SF=0 if result is negative ZF=1 if result equal to 0 ZF=0 if result not equal to 0 4-48 AF=1 if carry or borrow to low nibble AF=0 otherwise Instruction Set DEC DEC Examples This example sends events to another device. CMP, JE, DEC, and JMP implement a construct equivalent to the C-language while loop. COUNT DW 1048 ; send events to another device SEND: CMP COUNT,0 JE DONE CALL DEC JMP SEND_EVENT COUNT SEND ; number of events to send ; is count 0? ; if so, then jump out of loop ; send an event ; subtract 1 from counter ; jump to top of loop DONE: ... Tips Use SUB instead of DEC when you need to detect either a borrow to the highest bit of an unsigned result, or an integer result that is too large to fit in the destination. Use DEC within a loop when you want to decrease a value by 1 each time the loop is executed. The LOOP instruction can be used to combine the decrement (DEC CX only) and conditional jump into one instruction. Related Instructions If you want to See Add 1 to a number Set CF to 1 if there is a borrow to the highest bit of the unsigned result, or set OF to 1 if the integer result is too large to fit in the destination INC SUB Instruction Set 4-49 DIV Divide Unsigned Numbers DIV Form Opcode Description Clocks Am186 Am188 DIV r/m8 F6 /6 AL=AX/(r/m byte); AH=remainder 29/35 29/35 DIV r/m16 F7 /6 AX=DX::AX/(r/m word); DX=remainder 38/44 38/48 What It Does DIV divides one unsigned number by another unsigned number. Syntax DIV divisor Description DIV operates on unsigned numbers. The operand you specify is the divisor. DIV assumes that the number to be divided—the dividend—is in AX or DX::AX. (DIV uses a dividend that is twice the size of the divisor.) DIV replaces the high half of the dividend with the remainder and the low half of the dividend with the quotient. If the quotient is too large to fit in the low half of the dividend (such as when dividing by 0), DIV generates Interrupt 0 instead of setting CF. DIV truncates nonintegral quotients toward 0. Operation It Performs if (size(divisor) == 8) /* unsigned byte division */ { temp = AX / divisor; if (size(temp) > size(AL)) /* quotient too large */ interrupt(0); else { AH = AX % divisor; AL = temp; } } if (size(divisor) == 16) /* unsigned word division */ { temp = DX::AX / divisor; if (size(temp) > size(AX)) /* quotient too large */ interrupt(0); else { DX = DX::AX % divisor; AX = temp; } } 4-50 Instruction Set /* remainder */ /* quotient */ /* remainder */ /* quotient */ DIV DIV Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF ? – – – ? ? res ? res ? res ? 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Examples This example divides an 8-bit unsigned number by another 8-bit unsigned number. UDIVIDEND UDIVISOR DB DB 97 6 ; divide byte by byte MOV AL,UDIVIDEND MOV AH,0 DIV UDIVISOR ; 61h ; 06h ; ; ; ; AL AX AL AH = = = = 61h = 0061h 10h = 01h = 97 = 97 16, the quotient 1, the remainder This example divides a 32-bit unsigned number by a 16-bit unsigned number. Before dividing, the example checks the divisor to make sure it is not 0. This practice avoids division by 0, thereby preventing DIV from generating Interrupt 0. UDIVIDEND UDIVISOR DD DW 875600 57344 ; 000D5C50h ; E000h ; divide doubleword by word ; test for 0 divisor CMP UDIVISOR,0 JE DIV_ZERO ; is divisor 0? ; if so, then jump ; copy dividend to registers ; (bytes in memory are store in reverse order) MOV DX,WORD PTR UDIVIDEND+2 MOV AX,WORD PTR UDIVIDEND ; DX::AX = 000D5C50h DIV UDIVISOR ; AX = 000Fh = 15, ; the quotient ; DX = 3C50h = 15440, ; the remainder ... DIV_ZERO: ... Instruction Set 4-51 DIV DIV Tips DIV requires the dividend to be twice the size of the divisor. To convert an 8-bit unsigned dividend to its 16-bit equivalent (or a 16-bit dividend to its 32-bit equivalent), use MOV to load the high half with 0. If the unsigned dividend will fit in a 16-bit register and you don’t need the remainder, use SHR to divide unsigned numbers by powers of 2. When dividing an unsigned number by a power of 2, it is faster to use SHR than DIV. The Am186 and Am188 microcontrollers do not provide an instruction that performs decimal division. To divide a decimal number by another decimal number, use AAD to convert the dividend to binary and then perform binary division using DIV. Related Instructions If you want to See Convert a two-digit unpacked decimal dividend to its unsigned binary equivalent AAD 4-52 Divide an integer by another integer IDIV Divide an unsigned number by a power of 2 SHR Instruction Set 4 ENTER* Enter High-Level Procedure ENTER Clocks Am186 Am188 Form Opcode Description ENTER imm16,imm8 C8 iw ib Create stack frame for nested procedure ENTER imm16,0 C8 iw 00 ENTER imm16,1 C8 iw 01 22+16(n –1) 26+20(n –1) Create stack frame for non-nested procedure 15 19 Create stack frame for nested procedure 25 29 What It Does ENTER reserves storage on the stack for the local variables of a procedure. Syntax ENTER bytes,level Description ENTER creates the stack frame required by most block-structured high-level languages. The microcontroller uses BP as a pointer to the stack frame and SP as a pointer to the top of the stack. The first operand (bytes) specifies the number of stack bytes to allocate for the local variables of the procedure. The second operand (level) specifies the lexical nesting level (0–31) of the procedure within the high-level-language source code. The nesting level determines the number of stackframe pointers that are copied to the new stack frame from the preceding frame. If level is 0, ENTER pushes BP onto the stack, sets BP to the current value of SP, and subtracts bytes from SP. * – This instruction was not available on the original 8086/8088 systems. Instruction Set 4-53 ENTER ENTER Operation It Performs /* convert level to a number between 0 and 31 */ level = level % 32; /* save base and frame pointers */ push(BP); framePointer = SP; if (level > 0) /* reserve storage for each nesting level */ { for (i = 1;i < level;i++) { BP = BP - 2; push(BP); } push(framePointer); } /* update base and frame pointers */ BP = framePointer; SP = SP - bytes; Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Examples This example procedure uses ENTER to: push the current frame pointer (BP) onto the stack, set up BP to point to its stack frame, reserve 4 bytes on the stack for its local variables, and indicate that it is not called by another procedure. ; procedure that is not called by another Main PROC FAR ENTER 4,0 ; reserve 4 bytes for variables ; procedure is not called by another ; perform operations ... ; save AX PUSH AX ; perform operations ... LEAVE RET Main 4-54 2 ; remove variables from stack ; remove saved AX from stack ENDP Instruction Set ENTER ENTER This example includes two procedures, each of which uses ENTER to create its own stack frame. Each procedure uses LEAVE to destroy its stack frame before returning to the procedure that called it. ; top-level procedure Main PROC FAR ENTER 6,1 ; reserve 6 bytes for variables ; level 1 procedure ; perform operations ... Main LEAVE RET ENDP ; remove variables from stack ; second-level procedure Sub2 PROC FAR ENTER 20,2 ; reserve 20 bytes for variables ; level 2 procedure ; perform operations ... Sub2 LEAVE RET ENDP ; remove variables from stack Tips Before you use ENTER, use MOV to copy the stack segment to SS and the stack offset to SP. If a procedure is not called by another, then use ENTER with a level of 0. If a procedure is called by another, then use ENTER with a level of 1 for the main procedure, use ENTER with a level of 2 for the procedure it calls, and so on. Related Instructions If you want to See Remove the local variables of a procedure from the stack LEAVE Instruction Set 4-55 ESC* Escape ESC Clocks Am186 Am188 Form Opcode Description ESC m D8 /0 Takes trap 7. N/A N/A ESC m D9 /1 Takes trap 7. N/A N/A ESC m DA /2 Takes trap 7. N/A N/A ESC m DB /3 Takes trap 7. N/A N/A ESC m DC /4 Takes trap 7. N/A N/A ESC m DD /5 Takes trap 7. N/A N/A ESC m DE /6 Takes trap 7. N/A N/A ESC m DF /7 Takes trap 7. N/A N/A What It Does ESC is unimplemented and takes a trap 7. Syntax ESC opcode,source Description The Am186 and Am188 family of microcontrollers do not support a coprocessor interface. Operation It Performs INT 7 ; take trap 7 Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF PF CF – 0 0 – – res – res – res – 11 10 9 8 7 6 ? = undefined; – = unchanged * – This instruction is not supported with the necessary pinout. 4-56 AF – Instruction Set 5 4 3 2 1 0 HLT Halt HLT Clocks Am186 Am188 Form Opcode Description HLT F4 Suspend instruction execution 2 2 What It Does HLT causes the microcontroller to suspend instruction execution until it receives an interrupt request or it is reset. Syntax HLT Description HLT places the microcontroller in a suspended state, leaving the CS and IP registers pointing to the instruction following HLT. The microcontroller remains in the suspended state until one of the following events occurs: n An external device resets the microcontroller by asserting the RES signal. The microcontroller immediately clears its internal logic and enters a dormant state. Several clock periods after the external device de-asserts RES, the microcontroller begins fetching instructions. n The Interrupt-Enable Flag (IF) is 1 and an external device or peripheral asserts one of the microcontroller’s maskable interrupt requests that is not masked off by its interrupt control register (or an external device issues a nonmaskable interrupt request by asserting the microcontroller’s nonmaskable interrupt signal). The microcontroller resumes executing instructions at the location specified by the corresponding pointer in the microcontroller’s interrupt vector table. After the interrupt procedure is done, the microcontroller begins executing the sequence of instructions following HLT. Operation It Performs stopExecuting(); /* CS:IP points to the following instruction */ /* wait for interrupt or reset */ do { } while (!(interruptRequest() || nmiRequest() || resetRequest())) Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Instruction Set 4-57 HLT HLT Examples This example interrupt-service routine (ISR) flashes the LEDs that are mapped to eight of the microcontroller’s programmable input/output (PIO) pins and then suspends instruction execution. ; flash the LEDs a few times and stop executing instructions ISR_DEFAULT: PUSHA ; save general registers ; turn the PIOs on as outputs to the LEDs in case ; this has not already been done MOV DX,PIO_MODE0_ADDR MOV AX,0C07Fh OUT DX,AX MOV DX,PIO_DIR0_ADDR MOV AX,0 OUT DX,AX MOV CX,0FFh ISR_D_LOOP: MOV AX,0Fh mLED_OUTPUT MOV AX,0F0h mLED_OUTPUT DEC CX JNZ ISR_D_LOOP ; ; ; ; ; ; bottom 4 LEDs turn them on (macro) top 4 LEDs turn them on (macro) subtract 1 from counter if counter is not zero, then jump ; suspend instruction execution HLT ; return never expected, but just in case POPA ; restore general registers IRET ; return to interrupted procedure This example implements a polling of a PIO-based request, which is done based on a timer or any other interrupt. ; set up timer for periodic interrupts ; this specifies the maximum time between polls LOOP_START: HLT ; wait for an interrupt, then poll ; after ISR returns MOV AX,PIO_DATA0 TEST AX,PIO_ACTION_INDICATOR JNZ DO_ACTION JMP LOOP_START DO_ACTION: ; do whatever action needs to be taken JMP LOOP_START ;return to idle state 4-58 Instruction Set HLT HLT Tips If you want a procedure to wait for an interrupt request, use HLT instead of an endless loop. On-board peripherals including timers, serial ports, and DMA continue to operate in HLT. These devices may issue interrupts which bring the processor out of HLT. Related Instructions If you want to See Disable all maskable interrupts CLI Enable maskable interrupts that are not masked by their interrupt control registers STI Instruction Set 4-59 IDIV Divide Integers IDIV Clocks Am186 Am188 Form Opcode Description IDIV r/m8 F6 /7 AL=AX/(r/m byte); AH=remainder 44–52/50–58 44–52/50–58 IDIV r/m16 F7 /7 AX=DX::AX/(r/m word); DX=remainder 53–61/59–67 53–61/63–71 What It Does IDIV divides one integer by another integer. Syntax IDIV divisor Description IDIV operates on signed numbers (integers). The operand you specify is the divisor. IDIV assumes that the number to be divided (the dividend) is in AX or DX::AX. (IDIV uses the dividend that is twice the size of the divisor.) IDIV replaces the high half of the dividend with the remainder and the low half of the dividend with the quotient. As in traditional mathematics, the sign of the remainder is always the same as the sign of the dividend. If the quotient is too large to fit in the low half of the dividend (such as when dividing by 0), IDIV generates Interrupt 0 instead of setting OF. IDIV truncates nonintegral quotients toward 0. 4-60 Instruction Set IDIV IDIV Operation It Performs if (size(divisor) == 8) /* signed byte division */ { temp = AX / divisor; if (size(temp) > size(AL)) /* quotient too large */ interrupt(0); else { AH = AX % divisor; AL = temp; } /* remainder */ /* quotient */ } if (size(divisor) == 16) /* signed word division */ { temp = DX::AX / divisor; if (size(temp) > size(AX)) /* quotient too large */ interrupt(0); else { DX = DX::AX % divisor; AX = temp; } /* remainder */ /* quotient */ } Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF ? – – – ? ? res ? res ? res ? 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Examples This example divides one 16-bit integer by an 8-bit integer. SDIVIDEND SDIVISOR DW DB -14500 123 ; C75Ch ; 7Bh ; divide word integer by byte integer MOV AX,SDIVIDEND ; AX = C75Ch = -14500 IDIV SDIVISOR ; AL = 8Bh = -117, the quotient ; AH = 93h = -109, the remainder Instruction Set 4-61 IDIV IDIV This example divides one 16-bit integer by another. SDIVIDEND SDIVISOR DW DW 4800 -321 ; divide word integers MOV AX,SDIVIDEND CWD IDIV SDIVISOR ; 12C0h ; FEBFh ; ; ; ; AX = 12C0h = 4800 DX::AX = 000012C0h = 4800 AX = 00F2h = -14, the quotient DX = 0132h = -306, the remainder Tips IDIV requires the dividend to be twice the size of the divisor. To convert an 8-bit integer dividend to its 16-bit equivalent, use CBW. To convert a 16-bit dividend to its 32-bit equivalent, use CWD. If the integer dividend will fit in a 16-bit register and you don’t need the remainder, use SAR to divide integers by powers of 2. When dividing an integer by a power of 2, it is faster to use SAR than IDIV. When dividing unsigned numbers, use DIV instead of IDIV to make it obvious to someone who reads your code that you are operating on unsigned numbers. Related Instructions 4-62 If you want to See Convert an 8-bit integer dividend to its 16-bit equivalent Convert a 16-bit integer dividend to its 32-bit equivalent CBW CWD Divide an unsigned number by another unsigned number Change the sign of an integer DIV NEG Divide an integer by a power of 2 SAR Instruction Set IMUL* Multiply Integers IMUL Clocks Am186 Am188 Form Opcode Description IMUL r/m8 F6 /5 AX=(r/m byte)•AL 25–28/31–34 25–28/31–34 IMUL r/m16 F7 /5 DX::AX=(r/m word)•AX 34–37/40–43 34–37/44–47 IMUL r16,r/m16,imm8 6B /r ib (word register)=(r/m word)•(sign-ext. byte integer) 22–25 22–25 IMUL r16,imm8 6B /r ib (word register)=(word register)•(sign-ext. byte integer) 22–25 22–25 IMUL r16,r/m16,imm16 69 /r iw (word register)=(r/m word)•(sign-ext. word integer) 29–32 29–32 IMUL r16,imm16 69 /r iw (word register)=(word register)•(sign-ext. word integer) 29–32 29–32 What It Does IMUL multiplies two integers. Syntax IMUL multiplicand IMUL product,multiplicand,multiplier Use this form to multiply an integer in memory or in a register by AL or AX, and store the result in AX or DX::AX. IMUL product,multiplier Use this form to multiply an integer in a register by an immediate integer, and overwrite the register with the result. Use this form to multiply an integer in memory or in a register by an immediate integer, and specify the register in which to place the result. Description IMUL operates on signed numbers (integers). The operation it performs depends on the number of operands you specify. For example: n One operand: The operand you specify is the multiplicand. IMUL assumes that the integer by which it is to be multiplied (the multiplier) is in AL or AX. (IMUL uses the multiplier that is the same size as the multiplicand.) IMUL places the product in AX or DX::AX. (The destination is always twice the size of the multiplicand.) n Two operands: You specify the destination register for the product and the immediate integer by which the multiplicand is to be multiplied (the multiplier). IMUL uses the destination register as the multiplicand and then overwrites it with the product. n Three operands: This form of IMUL is the same as the two-operand form, except that IMUL preserves the multiplicand. You specify the destination register for the product, the multiplicand, and the immediate integer by which the multiplicand is to be multiplied (the multiplier). IMUL preserves the multiplicand. * – Integer immediate multiplies were not available on the original 8086/8088 systems. Instruction Set 4-63 IMUL IMUL Operation It Performs if (operands() == 1) /* multiply multiplicand with accumulator */ { if (size(multiplicand) == 8) /* signed byte multiplication */ { temp = multiplicand * AL; if (size(temp) == size(AL)) /* byte result */ { /* store result */ AL = temp; if (AL < 0) /* extend sign into AX */ AH = 0xFF; else AH = 0x00; /* clear overflow and carry flags */ OF = CF = 0; } else /* word result */ { /* store result */ AX = temp; /* set overflow and carry flags */ OF = CF = 1; } } if (size(multiplicand) == 16) /* signed word multiplication */ { temp = multiplicand * AX; if (size(temp) == size(AX)) /* word result */ { /* store result */ AX = temp; if (AX < 0) /* extend sign into DX */ DX = 0xFF; else DX = 0x00; /* clear overflow and carry flags */ OF = CF = 0; } else /* doubleword result */ { /* store result */ DX::AX = temp; /* set overflow and carry flags */ OF = CF = 1; } } } 4-64 Instruction Set IMUL IMUL /* (continued) */ if (operands() == 2) /* substitute ”product” for multiplicand */ multiplicand = product; if (operands() >= 2) { temp = multiplicand * multiplier; if (size(temp) == size(product)) /* product will fit */ { /* store result */ product = temp; /* clear overflow and carry flags */ OF = CF = 0; } else /* product won’t fit */ { /* store only lower half of result */ product = 0x00FF & temp; /* set overflow and carry flags */ OF = CF = 1; } } Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 11 IF TF SF ZF AF PF CF – – – ? ? res ? res ? res 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged For the single-operand form: For the two- and three-operand forms: CF and OF = 1 if the product is large enough to require the full destination. CF and OF = 1 if the product is too large to fit in the destination. CF and OF = 0 if the product is small enough to fit in the low half of the destination. CF and OF = 0 if the product is small enough to fit in the destination. Examples This example uses the single-operand form of IMUL to multiply an 8-bit integer in memory by an integer in AL. BMULTIPLICAND DB -10 ; F6h ; 8-bit integer multiplication: AX = BMULTIPLICAND * AL MOV AL,7 ; AL = 07h = 7 IMUL BMULTIPLICAND ; AX = FFBAh = -70 Instruction Set 4-65 IMUL IMUL Tips Use SAL instead of IMUL to multiply integers by powers of 2. When multiplying an integer by a power of 2, it is faster to use SAL than IMUL. When using the single-operand form of IMUL, you can often ignore the high half of the destination because the product is small enough to fit in only the low half of the destination. If it is, IMUL clears CF and OF to 0; otherwise, IMUL sets CF and OF to 1. When using the two- or three-operand forms of IMUL, the product can easily be large enough so that it does not fit in the destination. Before using the result of either of these forms, make sure that the destination contains the entire product. If it does, IMUL clears CF and OF to 0; otherwise, IMUL sets CF and OF to 1. Related Instructions 4-66 If you want to See Convert an 8-bit integer to its 16-bit equivalent CBW Multiply two unsigned numbers MUL Change the sign of an integer Multiply an integer by a power of 2 NEG SAL Instruction Set IN Input Component from Port IN Clocks Am186 Am188 Form Opcode Description IN AL,imm8 E4 ib Input byte from immediate port to AL 10 10 IN AX,imm8 E5 ib Input word from immediate port to AX 10 14 IN AL,DX EC Input byte from port in DX to AL 8 8 IN AX,DX ED Input word from port in DX to AX 8 12 What It Does IN copies a component from a port in I/O space to a register. Syntax IN destination,port Description IN transfers a data byte or word from the port numbered by the second operand (port) into the register (AL or AX) specified by the first operand (destination). Access any port from 0 to 65535 by placing the port number in the DX register and using an IN instruction with the DX register as the second operand. The upper eight bits of the port address will be 0 when an 8-bit port number is used. Operation It Performs if (size(port) == 8) /* extend port address */ port = 0x00FF & port; /* move component */ destination = [port]; Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Instruction Set 4-67 IN IN Examples This example reads ASCII characters from a port in I/O space to a string in memory. The microcontroller copies the bytes and stores them, one by one, from first to last. STRING DB 128 DUP (?) ; read characters from I/O port to string ; set up registers and flags LEA DI,STRING ; load offset into DI (segment = ES) MOV CX,LENGTH STRING ; set up counter CLD ; process string low to high READ_CHAR: IN STOSB LOOP AL,51h READ_CHAR ; copy character from I/O port to AL ; copy character from AL to string ; while CX is not 0, jump to top of loop Tips Use IN to talk to the peripheral registers, since they are initially set to I/O space (and not memory-mapped). Related Instructions 4-68 If you want to See Copy a component from a port in I/O memory to a string in main memory INS Copy a component from a register to a port in I/O memory Copy a component from a string in main memory to a port in I/O memory OUT OUTS Instruction Set INC Increment Number by One INC Form Opcode Description Clocks Am186 Am188 INC r/m8 FE /0 Increment r/m byte by 1 3/15 3/15 INC r/m16 FF /0 Increment r/m word by 1 3/15 3/19 INC r16 40+ rw Increment word register by 1 3 3 What It Does INC adds 1 to an integer or an unsigned number. Syntax INC addend Description INC adds 1 to the operand. Operation It Performs /* increment addend */ addend = addend + 1; Flag Settings After Instruction OF DF Processor Status Flags Register 15 14 13 12 11 IF TF SF ZF – – – 10 9 8 reserved AF res 7 6 5 PF res 4 3 CF res – 2 1 0 ? = undefined; – = unchanged OF=1 if result larger than destination operand OF=0 otherwise PF=1 if low byte of result has even number of set bits PF=0 otherwise SF=1 if result is 0 or positive SF=0 if result is negative ZF=1 if result equal to 0 ZF=0 if result not equal to 0 AF=1 if carry or borrow to low nibble AF=0 otherwise Instruction Set 4-69 INC INC Examples This example writes pixel values to a buffer. INC, CMP, and JL implement a construct equivalent to the C-language do-while loop. COUNT DB 128 ; write pixel values to buffer MOV CL,0 ; set up counter WRITE: ; write a pixel CALL WRITE_PIXEL INC CMP JL CL CL,COUNT WRITE ; add 1 to counter ; have all pixels been written? ; if not, then jump to top of loop Tips Use ADD instead of INC when you need to detect a carry from the highest bit of an unsigned result, or detect a signed result that is too large to fit in the destination. Use INC within a loop when you want to increase a value by 1 each time the loop is executed. Related Instructions 4-70 If you want to See Add two numbers Subtract 1 from a number ADD DEC Instruction Set INS* INSB INSW Input String Component from Port Input String Byte from Port Input String Word from Port INS Clocks Am186 Am188 Form Opcode Description INS m8,DX 6C Input byte from port in DX to ES:[DI] 14 14 INS m16,DX 6D Input word from port in DX to ES:[DI] 14 14 INSB 6C Input byte from port in DX to ES:[DI] 14 14 INSW 6D Input word from port in DX to ES:[DI] 14 14 What It Does INS copies a component from a port in I/O space to a string in memory. Syntax INS destination,port INSB INSW To have the assembler type-check your operands, use this form. The assembler uses the definition of the string component to determine its size. Regardless of the form of INS you use, destination is always ES:[DI], and port is always DX. Before using To copy a byte from the I/O port any form of INS, make sure that: ES specified in DX to a byte within a string contains the segment of the string, DI located in the segment specified in contains the offset of the string, and ES, use this form. DX contains the number of the port. To copy a word from the I/O port specified in DX to a word within a string located in the segment specified in ES, use this form. Description INS transfers data from the input port numbered by the DX register to the memory byte or word at ES:DI. The memory operand must be addressable from the ES register; no segment override is possible. The INS instruction does not allow the specification of the port number as an immediate value. You must address the port through the DX register value. Similarly, the destination index register determines the destination address. Before executing the INS instruction, you must preload the DX register value into the DX register and the correct index into the destination index register. After the transfer is made, the DI register advances automatically. If DF is 0 (a CLD instruction was executed), the DI register increments; if DF is 1 (an STD instruction was executed), the DI register decrements. The DI register increments or decrements by 1 if the input is a byte, or by 2 if it is a word. The INSB and INSW instructions are synonyms for the byte and word INS instructions, respectively. * – This instruction was not available on the original 8086/8088 systems. Instruction Set 4-71 INS INS Operation It Performs if (size(destination) == 8) /* input bytes */ { ES:DI = [DX]; if DF == 0 increment = 1; else increment = -1; } /* byte in I/O memory */ /* forward */ /* backward */ if (size(destination) == 16) /* input words */ { ES:DI = [DX]; if DF == 0 increment = 2; else increment = -2; } /* word in I/O memory */ /* forward */ /* backward */ /* point to location for next string component */ DI = DI + increment; Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Tips Before using INS, always be sure to: set up ES:[DI] with the offset of the string, set up CX with the length of the string, and use CLD (forward) or STD (backward) to establish the direction for string processing. The string instructions always advance SI and/or DI, regardless of the use of the REP prefix. Be sure to set or clear DF before any string instruction. Related Instructions 4-72 If you want to See Process string components from lower to higher addresses Copy a component from a port in I/O memory to a register CLD IN Copy a component from a register to a port in I/O memory Copy a component from a string in main memory to a port in I/O memory OUT OUTS Repeat one string instruction Process string components from higher to lower addresses REP STD Instruction Set INT INTO Generate Interrupt Generate Interrupt If Overflow INT Clocks Am186 Am188 Form Opcode Description INT 3 CC Generate interrupt 3 (trap to debugger) 45 45 INT imm8 CD ib Generate type of interrupt specified by immediate byte 47 47 INTO CE Generate interrupt 4 if Overflow Flag (OF) is 1 48,4 48,4 What It Does INT generates an interrupt via software. Syntax INT type To generate an unconditional interrupt, use this form INTO To generate an interrupt only if OF is set to 1, use this form. When OF is 1, this form is the same as INT 4. Description INT suspends execution of the current procedure, pushes the Processor Status Flags (FLAGS) register and the segment (CS) and offset (IP) addresses of the next instruction onto the stack, and begins executing an interrupt handler (also known as an interrupt service routine). The operand you specify is the interrupt type, which can range from 0 to 255. The microcontroller computes the address of the appropriate vector in the interrupt vector table by shifting type left two times (in effect, multiplying it by 4). Then the microcontroller jumps to the interrupt handler pointed to by that vector. INTO is a conditional form of INT that is specifically used to handle arithmetic overflow conditions. If the Overflow Flag (OF) is set to 1 when the microcontroller executes INTO, then INTO generates a type 4 interrupt. This is equivalent to executing INT 4. If OF is cleared to 0, INTO does nothing, and the microcontroller begins executing the instruction following INTO. Am186 and Am188 microcontrollers reserve some of the low-numbered interrupts for software traps and exceptions, and for on-board peripheral devices. See the User’s Manual for the specific device for more information. IF is not cleared automatically when executing a software interrupt trap. No end-of-interrupt (EOI) is required even if the interrupt type is the same as that for a peripheral. Instruction Set 4-73 INT INT Operation It Performs /* save flags */ push(FLAGS); /* clear trap and interrupt flags */ TF = IF = 0; /* save address of next instruction */ push(CS); push(IP); /* /* CS IP begin execution at location indicated by vector */ in interrupt vector table */ /* CS value is fetched at address type shifted by 2 */ = [type << 2;] /* IP value is fetched at address type */ = [(type << 2) + 2;] /* shifted by 2, plus 2 */ Flag Settings After Instruction If INTO does not take an interrupt, flags are not affected. Otherwise, flags for INT and INTO are affected as shown below: OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – 0 0 – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Tips Before using INT, use MOV to copy the stack segment to SS and the stack offset to SP. When the Interrupt-Enable Flag (IF) is cleared to disable all maskable interrupts, INT can be used to generate an interrupt, even if it is masked by its interrupt control register. INT operates like a far call except that the contents of the Processor Status Flags register are pushed onto the stack before the return address. Unlike interrupts generated by external hardware, INT does not set an interrupt’s in-service bit in the In-Service (INSERV) register. Use IRET to end an interrupt handler and resume the interrupted procedure. 4-74 Instruction Set INT INT Related Instructions If you want to See Call a procedure End an interrupt handler and resume the interrupted procedure CALL IRET End a procedure and return to the calling procedure RET Instruction Set 4-75 IRET Interrupt Return IRET Clocks Am186 Am188 Form Opcode Description IRET CF Return from interrupt handler to interrupted procedure 28 28 What It Does IRET ends an interrupt handler and resumes the interrupted procedure. Syntax IRET Description Used at the end of an interrupt handler, IRET restores the Instruction Pointer (IP) register, the Code Segment (CS) register, and the Processor Status Flags (FLAGS) register from the stack, and then resumes the interrupted procedure. Operation It Performs /* restore address of next instruction */ IP = pop(); CS = pop(); /* restore flags */ FLAGS = pop(); Flag Settings After Instruction Processor Status Flags Register OF DF IF TF SF ZF 11 9 res reserved 15 14 13 AF 12 10 8 7 6 5 PF res 4 3 ? = undefined; – = unchanged Restores value of FLAGS register that was stored on the stack when the interrupt was taken. 4-76 Instruction Set CF res 2 1 0 IRET IRET Examples This example interrupt-service routine resets the Timer 1 Count (T1CNT) register. ; reset Timer 1 ISR_T0: PUSHA ; save general registers ; reset MOV MOV OUT Timer 1 DX,TMR1_CNT_ADDR AX,0 DX,AX ; address of T1CNT register ; reset count ; write count to register ; clear MOV MOV OUT in-service bit DX,INT_EOI_ADDR AX,ITYPE_TMR0 DX,AX ; address of End-Of-Interrupt (EOI) register ; EOI type ; clear in-service bit POPA IRET ; restore general registers Tips IRET always performs a far return, restoring both IP and CS, and then popping the Processor Status Flags register from the stack. Related Instructions If you want to See Call a procedure CALL Clear the interrupt-enable flag and disable all maskable interrupts Generate a software interrupt CLI INT End a procedure and return to the calling procedure Set the interrupt-enable flag, enabling all maskable interrupts RET STI Instruction Set 4-77 4 JA JNBE Jump If Above Jump If Not Below or Equal JA Form Opcode Description Clocks Am186 Am188 JA rel8 77 cb Jump short if above (CF=0 and ZF=0) 13,4 13,4 JNBE rel8 77 cb Jump short if not below or equal (CF=0 and ZF=0) 13,4 13,4 What It Does If the previous instruction clears the Carry Flag (CF) and the Zero Flag (ZF), JA and JNBE stop executing the current sequence of instructions and begin executing a new sequence of instructions; otherwise, execution continues with the next instruction. Syntax JA label JNBE label To jump if the result of a previous unsigned comparison was above, use JA or its synonym, JNBE. Both forms perform the same operation. Description JA and JNBE test the flags set by a previous instruction. The terms above and below indicate an unsigned number comparison. If the given condition is true, a short jump is made to the location provided as the operand. Operation It Performs if ((CF == 0) && (ZF == 0)) { /* extend sign of label */ if (label < 0) displacement = 0xFF00 | label; else displacement = 0x00FF & label; /* branch to labeled instruction */ IP = IP + displacement; } Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 ? = undefined; – = unchanged 4-78 AF Instruction Set 5 4 3 2 1 0 JA JA Examples This example converts a zero-terminated string to uppercase and replaces the original string. astring dup30db (?) ; set DS:[SI] and ES:[DI] to both point to astring PUSH PUSH DS ES ; save DS and ES MOV MOV MOV MOV MOV AX, SEG astring DS,AX ES,AX DI,offset astring SI,offset astring LCONVERT_START: LODSB CMP JB CMP JA ADD AL,[SI] AL,’a’ LWRITE_IT AL,’z’ LWRITE_IT AL,’A’-’a’ LWRITE_IT: STOSB CMP JNE POP POP AL,0 LCONVERT_START ES DS ; ; ; ; ; ; get the character in AL compare against ’a’ not in range, don’t convert compare against ’z’ not in range, don’t convert convert ; ; ; ; write it out are we done? not done so loop restore original DS and ES values Tips If you need to jump to an instruction at farlabel that is more than 128 bytes away, use the following sequence of statements: JNA nearlabel JMP farlabel nearlabel: ; This does the equivalent of a long jump ; based on the JA condition. Related Instructions If you want to See Compare two components using subtraction and set the flags accordingly CMP Jump if the result of a previous unsigned comparison was below or equal JBE Jump if the result of a previous integer comparison was greater Jump unconditionally JG JMP Set the flags according to whether particular bits of a component are set to 1 TEST Instruction Set 4-79 JAE JNB JNC Jump If Above or Equal Jump If Not Below Jump If Not Carry JAE Form Opcode Description Clocks Am186 Am188 JAE rel8 73 cb Jump short if above or equal (CF=0) 13,4 13,4 JNB rel8 73 cb Jump short if not below (CF=0) 13,4 13,4 JNC rel8 73 cb Jump short if not carry (CF=0) 13,4 13,4 What It Does If the previous instruction clears the Carry Flag (CF), JAE, JNB, and JNC stop executing the current sequence of instructions and begin executing a new sequence of instructions; otherwise, execution continues with the next instruction. Syntax JAE label JNB label To jump if the result of a previous unsigned comparison was above or equal, use JAE or one of its synonyms, JNB or JNC. Each form performs the same operation. JNC label Description JAE, JNB, and JNC test the flag set by a previous instruction. The terms above and below indicate an unsigned number comparison. If the given condition is true, a short jump is made to the location provided as the operand. Operation It Performs if (CF == 0) { /* extend sign of label */ if (label < 0) displacement = 0xFF00 | label; else displacement = 0x00FF & label; /* branch to labeled instruction */ IP = IP + displacement; } Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF PF CF – – – – – res – res – res – 11 10 9 8 7 6 ? = undefined; – = unchanged 4-80 AF – Instruction Set 5 4 3 2 1 0 JAE JAE Tips If you need to jump to an instruction at farlabel that is more than 128 bytes away, use the following sequence of statements: JNAE nearlabel JMP farlabel nearlabel: ; This does the equivalent of a long jump ; based on the JAE condition. Related Instructions If you want to See Compare two components using subtraction and set the flags accordingly CMP Jump if the result of a previous unsigned comparison was below JB Jump if the result of a previous integer comparison was greater or equal Jump unconditionally JGE JMP Set the flags according to whether particular bits of a component are set to 1 TEST Instruction Set 4-81 JB JC JNAE Jump If Below Jump If Carry Jump If Not Above or Equal JB Form Opcode Description Clocks Am186 Am188 JB rel8 72 cb Jump short if below (CF=1) 13,4 13,4 JC rel8 72 cb Jump short if carry (CF=1) 13,4 13,4 JNAE rel8 72 cb Jump short if not above or equal (CF=1) 13,4 13,4 What It Does If the previous instruction sets the Carry Flag (CF), JB, JC, and JNAE stop executing the current sequence of instructions and begin executing a new sequence of instructions; otherwise, execution continues with the next instruction. Syntax JB label JC label JNAE label To jump if the result of a previous unsigned comparison was below or equal, use JB or one of its synonyms, JC or JNAE. Each form performs the same operation. Description JB, JC, and JNAE test the flag set by a previous instruction. The terms above and below indicate an unsigned number comparison. If the given condition is true, a short jump is made to the location provided as the operand. Operation It Performs if (CF == 1) { /* extend sign of label */ if (label < 0) displacement = 0xFF00 | label; else displacement = 0x00FF & label; /* branch to labeled instruction */ IP = IP + displacement; } Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 ? = undefined; – = unchanged 4-82 AF Instruction Set 5 4 3 2 1 0 JB JB Examples This example checks the selection of 10 numbered items. ; check selection of 0-n+ item Num_items=10 ; 10 total items numbered (0-9) START_SEL: mGetSelection CMP AL,Num_items JNAE SEL_GOOD mPrintError JMP START_SEL ; value in AL ; compare to max# of items ; okay, selection in 0-(n-1) SEL_GOOD: ... Tips If you need to jump to an instruction at farlabel that is more than 128 bytes away, use the following sequence of statements: JNB nearlabel JMP farlabel nearlabel: ; This does the equivalent of a long jump ; based on the JB condition. Related Instructions If you want to See Compare two components using subtraction and set the flags accordingly Jump if the result of a previous unsigned comparison was above or equal CMP JAE Jump if the result of a previous integer comparison was less Jump unconditionally JL JMP Set the flags according to whether particular bits of a component are set to 1 TEST Instruction Set 4-83 JBE JNA Jump If Below or Equal Jump If Not Above JBE Form Opcode Description Clocks Am186 Am188 JBE rel8 76 cb Jump short if below or equal (CF=1 or ZF=1) 13,4 13,4 JNA rel8 76 cb Jump short if not above (CF=1 or ZF=1) 13,4 13,4 What It Does If the previous instruction sets the Carry Flag (CF) or the Zero Flag (ZF), JBE and JNA stop executing the current sequence of instructions and begin executing a new sequence of instructions; otherwise, execution continues with the next instruction. Syntax JBE label JNA label To jump if the result of a previous unsigned comparison was below or equal, use JBE or its synonym, JNA. Both forms perform the same operation. Description JBE and JNA test the flags set by a previous instruction. The terms above and below indicate an unsigned number comparison. If the given condition is true, a short jump is made to the location provided as the operand. Operation It Performs if ((CF == 1) || (ZF == 1)) { /* extend sign of label */ if (label < 0) displacement = 0xFF00 | label; else displacement = 0x00FF & label; /* branch to labeled instruction */ IP = IP + displacement; } Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF PF CF – – – – – res – res – res – 11 10 9 8 7 6 ? = undefined; – = unchanged 4-84 AF – Instruction Set 5 4 3 2 1 0 JBE JBE Tips If you need to jump to an instruction at farlabel that is more than 128 bytes away, use the following sequence of statements: JNBE nearlabel JMP farlabel nearlabel: ; This does the equivalent of a long jump ; based on the JBE condition. Related Instructions If you want to See Compare two components using subtraction and set the flags accordingly CMP Jump if the result of a previous unsigned comparison was above JA Jump if the result of a previous integer comparison was less or equal Jump unconditionally JLE JMP Set the flags according to whether particular bits of a component are set to 1 TEST Instruction Set 4-85 JC Jump If Carry JC Form Opcode Description Clocks Am186 Am188 JC rel8 72 cb Jump short if carry (CF=1) 13,4 13,4 What It Does If the previous instruction sets the Carry Flag (CF), JB, JC, and JNAE stop executing the current sequence of instructions and begin executing a new sequence of instructions; otherwise, execution continues with the next instruction. See JB on page 4-82 for a complete description. 4-86 Instruction Set JCXZ Jump If CX Register Is Zero JCXZ Form Opcode Description Clocks Am186 Am188 JCXZ rel8 E3 cb Jump short if CX register is 0 15,5 15,5 What It Does If the previous instruction leaves 0 in CX, JCXZ stops executing the current sequence of instructions and begins executing a new sequence of instructions; otherwise, execution continues with the next instruction. Syntax JCXZ label To jump if CX is 0, use JCXZ. Description JCXZ tests the CX register modified by a previous instruction. If the given condition is true (CX=0), a short jump is made to the location provided as the operand. Operation It Performs if (CX == 0) { /* extend sign of label */ if (label < 0) displacement = 0xFF00 | label; else displacement = 0x00FF & label; /* branch to labeled instruction */ IP = IP + displacement; } Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Instruction Set 4-87 JCXZ JCXZ Examples This example waits for a character from the serial port. DEC, JCXZ, and JMP implement a construct equivalent to the C-language do-while loop. CMP and JNE implement an if statement within the loop. ; loop for a maximum number of times or until a ; serial-port character is ready MOV CX,100h LOOP_TOP: mCHAR_READY CMP AH,0 JNE GOT_CHAR DEC CX JCXZ NO_CHAR JMP LOOP_TOP ; set up counter ; ; ; ; ; ; read character into AH (macro) is a character ready? if so, then jump out with character subtract 1 from counter if CX is 0, jump out without character if not, jump to top of loop GOT_CHAR: ... NO_CHAR: ... Tips Use JCXZ to determine if CX is 0 before executing a loop that does not check the value of CX until the bottom of the loop. Related Instructions If you want to See Jump to the top of a loop if CX is not 0 LOOP Jump to the top of a loop if CX is not 0 and two compared components are equal LOOPE Jump to the top of a loop if CX is not 0 and two compared components are not equal LOOPNE 4-88 Instruction Set JE JZ Jump If Equal Jump If Zero JE Form Opcode Description Clocks Am186 Am188 JE rel8 74 cb Jump short if equal (ZF=1) 13,4 13,4 JZ rel8 74 cb Jump short if 0 (ZF=1) 13,4 13,4 What It Does If the previous instruction sets the Zero Flag (ZF), JE and JZ stop executing the current sequence of instructions and begin executing a new sequence of instructions; otherwise, execution continues with the next instruction. Syntax JE label JZ label To jump if the result of a previous integer or unsigned comparison was equal, use JE or its synonym, JZ. Both forms perform the same function. Description JE and JZ test the flag set by a previous instruction. If the given condition is true (ZF=1), a short jump is made to the location provided as the operand. Operation It Performs if (ZF == 1) { /* extend sign of label */ if (label < 0) displacement = 0xFF00 | label; else displacement = 0x00FF & label; /* branch to labeled instruction */ IP = IP + displacement; } Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Instruction Set 4-89 JE JE Examples This example reads a character from the serial port, and then uses that character to select a menu item. CMP, JE, and JMP implement a construct equivalent to the C-language switch statement. ; display menu and read character from serial port into AX MENU: mREAD_SPORT_CHAR ; read character into AX (macro) CMP JE AX,’1’ ITEM1 ; did user select item 1? ; if so, then jump CMP JE AX,’2’ ITEM2 ; did user select item 2? ; if so, then jump ; if user didn’t select valid item, jump back to menu JMP MENU ITEM1: ... ITEM2: ... Tips If you need to jump to an instruction at farlabel that is more than 128 bytes away, use the following sequence of statements: JNE nearlabel JMP farlabel nearlabel: ; This does the equivalent of a long jump ; based on the JE condition. Related Instructions 4-90 If you want to See Compare two components using subtraction and set the flags accordingly Jump unconditionally CMP JMP Jump if the result of a previous integer or unsigned comparison was not equal Set the flags according to whether particular bits of a component are set to 1 JNE TEST Instruction Set JG JNLE Jump If Greater Jump If Not Less or Equal JG Form Opcode Description Clocks Am186 Am188 JG rel8 7F cb Jump short if greater (ZF=0 and SF=OF) 13,4 13,4 JNLE rel8 7F cb Jump short if not less or equal (ZF=0 and SF=OF) 13,4 13,4 What It Does If the previous instruction clears the Zero Flag (ZF), and modifies the Sign Flag (SF) and the Overflow Flag (OF) so that they are the same, JG and JNLE stop executing the current sequence of instructions and begin executing a new sequence of instructions; otherwise, execution continues with the next instruction. Syntax JG label JNLE label To jump if the result of a previous integer comparison was greater, use JG or its synonym, JNLE. Both forms perform the same operation. Description JG and JNLE test the flags set by a previous instruction. The terms greater and less indicate an integer (signed) comparison. If the given condition is true (ZF=0 and SF=OF), a short jump is made to the location provided as the operand. Operation It Performs if ((ZF == 0) && (SF == OF)) { /* extend sign of label */ if (label < 0) displacement = 0xFF00 | label; else displacement = 0x00FF & label; /* branch to labeled instruction */ IP = IP + displacement; } Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Instruction Set 4-91 JG JG Tips If you need to jump to an instruction at farlabel that is more than 128 bytes away, use the following sequence of statements: JNG nearlabel JMP farlabel nearlabel: ; This does the equivalent of a long jump ; based on the JG condition. Related Instructions 4-92 If you want to See Compare two components using subtraction and set the flags accordingly CMP Jump if the result of a previous unsigned comparison was above JA Jump if the result of a previous integer comparison was less or equal Jump unconditionally JLE JMP Set the flags according to whether particular bits of a component are set to 1 TEST Instruction Set JGE JNL Jump If Greater or Equal Jump If Not Less JGE Form Opcode Description Clocks Am186 Am188 JGE rel8 7D cb Jump short if greater or equal (SF=OF) 13,4 13,4 JNL rel8 7D cb Jump short if not less (SF=OF) 13,4 13,4 What It Does If the previous instruction modifies the Sign Flag (SF) and the Overflow Flag (OF) so that they are the same, JGE and JNL stop executing the current sequence of instructions and begin executing a new sequence of instructions; otherwise, execution continues with the next instruction. Syntax JGE label JNL label To jump if the result of a previous integer comparison was greater or equal, use JGE or its synonym, JNL. Both forms perform the same operation. Description JGE and JNL test the flags set by a previous instruction. The terms greater and less indicate an integer (signed) comparison. If the given condition is true (SF=OF), a short jump is made to the location provided as the operand. Operation It Performs if (SF == OF) { /* extend sign of label */ if (label < 0) displacement = 0xFF00 | label; else displacement = 0x00FF & label; /* branch to labeled instruction */ IP = IP + displacement; } Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Instruction Set 4-93 JGE JGE Tips If you need to jump to an instruction at farlabel that is more than 128 bytes away, use the following sequence of statements: JNGE nearlabel JMP farlabel nearlabel: ; This does the equivalent of a long jump ; based on the JGE condition. Related Instructions 4-94 If you want to See Compare two components using subtraction and set the flags accordingly CMP Jump if the result of a previous unsigned comparison was above or equal JAE Jump if the result of a previous integer comparison was less Jump unconditionally JL JMP Set the flags according to whether particular bits of a component are set to 1 TEST Instruction Set JL JNGE Jump If Less Jump If Not Greater or Equal JL Form Opcode Description Clocks Am186 Am188 JL rel8 7C cb Jump short if less (SF≠ OF) 13,4 13,4 JNGE rel8 7C cb Jump short if not greater or equal (SF≠OF) 13,4 13,4 What It Does If the previous instruction modifies the Sign Flag (SF) and the Overflow Flag (OF) so that they are not the same, JL and JNGE stop executing the current sequence of instructions and begin executing a new sequence of instructions; otherwise, execution continues with the next instruction. Syntax JL label JNGE label To jump if the result of a previous integer comparison was less, use JL or its synonym, JNGE. Both forms perform the same operation. Description JL and JNGE test the flags set by a previous instruction. The terms greater and less indicate an integer (signed) comparison. If the given condition is true (SF≠OF), a short jump is made to the location provided as the operand. Operation It Performs if (SF != OF) { /* extend sign of label */ if (label < 0) displacement = 0xFF00 | label; else displacement = 0x00FF & label; /* branch to labeled instruction */ IP = IP + displacement; } Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Instruction Set 4-95 JL JL Tips If you need to jump to an instruction at farlabel that is more than 128 bytes away, use the following sequence of statements: JNL nearlabel JMP farlabel nearlabel: ; This does the equivalent of a long jump ; based on the JL condition. Related Instructions 4-96 If you want to See Compare two components using subtraction and set the flags accordingly CMP Jump if the result of a previous unsigned comparison was below JB Jump if the result of a previous integer comparison was greater or equal Jump unconditionally JGE JMP Set the flags according to whether particular bits of a component are set to 1 TEST Instruction Set JLE JNG Jump If Less or Equal Jump If Not Greater JLE Form Opcode Description Clocks Am186 Am188 JLE rel8 7E cb Jump short if less or equal (ZF=1 or SF≠OF) 13,4 13,4 JNG rel8 7E cb Jump short if not greater (ZF=1 or SF≠OF) 13,4 13,4 What It Does If the previous instruction sets the Zero Flag (ZF), or modifies the Sign Flag (SF) and the Overflow Flag (OF) so that they are not the same, JLE and JNG stop executing the current sequence of instructions and begin executing a new sequence of instructions; otherwise, execution continues with the next instruction. Syntax JLE label JNG label To jump if the result of a previous integer comparison was less or equal, use JLE or its synonym, JNG. Both forms perform the same operation. Description JLE and JNG test the flags set by a previous instruction. The terms greater and less indicate an integer (signed) comparison. If the given condition is true (ZF=1 or SF≠OF), a short jump is made to the location provided as the operand. Operation It Performs if ((ZF == 1) || (SF != OF)) { /* extend sign of label */ if (label < 0) displacement = 0xFF00 | label; else displacement = 0x00FF & label; /* branch to labeled instruction */ IP = IP + displacement; } Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Instruction Set 4-97 JLE JLE Tips If you need to jump to an instruction at farlabel that is more than 128 bytes away, use the following sequence of statements: JNLE nearlabel JMP farlabel nearlabel: ; This does the equivalent of a long jump ; based on the JLE condition. Related Instructions 4-98 If you want to See Compare two components using subtraction and set the flags accordingly CMP Jump if the result of a previous unsigned comparison was below or equal JBE Jump if the result of a previous integer comparison was greater Jump unconditionally JG JMP Set the flags according to whether particular bits of a component are set to 1 TEST Instruction Set JMP Jump Unconditionally JMP Clocks Am186 Am188 Form Opcode Description JMP rel8 EB cb Jump short direct, displacement relative to next instruction 14 14 JMP rel16 E9 cw Jump near direct, displacement relative to next instruction 14 14 JMP r/m16 FF /4 Jump near indirect 11/17 11/21 JMP ptr16:16 EA cd Jump far direct to doubleword immediate address 14 14 JMP m16:16 FF /5 Jump m16:16 indirect and far 26 34 What It Does JMP stops executing the current sequence of instructions and begins executing a new sequence of instructions. Syntax JMP label To jump unconditionally, use JMP. Description JMP transfers control to a different point in the instruction stream without recording return information. The instruction has several different forms, as follows: n Short Jumps: To determine the destination, the JMP rel8 form adds a signed offset to the address of the instruction following JMP. This offset can range from 128 bytes before or 127 bytes after the instruction following JMP. JMP rel16 and JMP r/m16 are near jumps. They use the current segment register value. n Near Direct Jumps: To determine the destination, the JMP rel16 form adds an offset to the address of the instruction following JMP. The JMP rel16 form is used for 16-bit operand-size attributes (segment-size attribute 16 only). The result is stored in the 16bit IP register. n Near Indirect Jumps: The JMP r/m16 form specifies a register or memory location from which the procedure absolute offset is fetched. The offset is 16 bits. JMP ptr16:16 and JMP m16:16 are far jumps. They use a long pointer to the destination. The long pointer provides 16 bits for the CS register and 16 bits for the IP register. n Far Direct Jumps: The JMP ptr16:16 form uses a 4-byte operand as a long pointer to the destination. n Far Indirect Jumps: The JMP m16:16 form fetches the long pointer from the specified memory location (an indirect jump). Instruction Set 4-99 JMP JMP Operation It Performs if (label == rel8)/* short direct */ { /* extend sign of label */ if (label < 0) displacement = 0xFF00 | label; else displacement = 0x00FF & label; /* branch to labeled instruction */ IP = IP + displacement; } if (label == rel16)/* near direct */ /* branch to labeled instruction */ IP = IP + label; if (label == r/m16)/* near indirect */ /* branch to labeled instruction */ IP = [label]; if (label == ptr16:16)/* far direct */ /* branch to labeled instruction */ CS:IP = label; if (label == m16:16)/* far indirect */ /* branch to labeled instruction */ CS:IP = [label]; Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 ? = undefined; – = unchanged 4-100 AF Instruction Set 5 4 3 2 1 0 JMP JMP Examples This example uses the integer in DX to determine the course of action. CMP and JL implement a construct equivalent to a C-language if statement. CMP, JG, and JMP implement an if-else statement. ; branch according to the value of the integer in DX CMP JL JG JMP DX,0 NEAR_NEG NEAR_POS FAR_ZERO ; ; ; ; is DX negative? if so, jump to near label if DX > 0, jump to near label else, jump to far label (DX is 0) NEAR_NEG: ... NEAR_POS: ... ; different code segment FAR_ZERO: ... Tips JMP is the only jump instruction that transfers execution to a far address (modifies both CS and IP). Related Instructions If you want to See Call a procedure CALL Instruction Set 4-101 JNA Jump If Not Above JNA Form Opcode Description Clocks Am186 Am188 JNA rel8 76 cb Jump short if not above (CF=1 or ZF=1) 13,4 13,4 What It Does If the previous instruction sets the Carry Flag (CF) or the Zero Flag (ZF), JBE and JNA stop executing the current sequence of instructions and begin executing a new sequence of instructions; otherwise, execution continues with the next instruction. See JBE on page 4-84 for a complete description. 4-102 Instruction Set JNAE Jump If Not Above or Equal JNAE Form Opcode Description Clocks Am186 Am188 JNAE rel8 72 cb Jump short if not above or equal (CF=1) 13,4 13,4 What It Does If the previous instruction sets the Carry Flag (CF), JB, JC, and JNAE stop executing the current sequence of instructions and begin executing a new sequence of instructions; otherwise, execution continues with the next instruction. See JB on page 4-82 for a complete description. Instruction Set 4-103 JNB Jump If Not Below JNB Form Opcode Description Clocks Am186 Am188 JNB rel8 73 cb Jump short if not below (CF=0) 13,4 13,4 What It Does If the previous instruction clears the Carry Flag (CF), JAE, JNB, and JNC stop executing the current sequence of instructions and begin executing a new sequence of instructions; otherwise, execution continues with the next instruction. See JAE on page 4-80 for a complete description. 4-104 Instruction Set JNBE Jump If Not Below or Equal JNBE Form Opcode Description Clocks Am186 Am188 JNBE rel8 77 cb Jump short if not below or equal (CF=0 and ZF=0) 13,4 13,4 What It Does If the previous instruction clears the Carry Flag (CF) and the Zero Flag (ZF), JA and JNBE stop executing the current sequence of instructions and begin executing a new sequence of instructions; otherwise, execution continues with the next instruction. See JA on page 4-78 for a complete description. Instruction Set 4-105 JNC Jump If Not Carry JNC Form Opcode Description Clocks Am186 Am188 JNC rel8 73 cb Jump short if not carry (CF=0) 13,4 13,4 What It Does If the previous instruction clears the Carry Flag (CF), JAE, JNB, and JNC stop executing the current sequence of instructions and begin executing a new sequence of instructions; otherwise, execution continues with the next instruction. See JAE on page 4-80 for a complete description. 4-106 Instruction Set JNE JNZ Jump If Not Equal Jump If Not Zero JNE Form Opcode Description Clocks Am186 Am188 JNE rel8 75 cb Jump short if not equal (ZF=0) 13,4 13,4 JNZ rel8 75 cb Jump short if not zero (ZF=0) 13,4 13,4 What It Does If the previous instruction clears the Zero Flag (ZF), JNE and JNZ stop executing the current sequence of instructions and begin executing a new sequence of instructions; otherwise, execution continues with the next instruction. Syntax JNE label JNZ label To jump if the result of a previous integer comparison was not equal, use JNE or its synonym, JNZ. Both forms perform the same operation. Description JNE and JNZ test the flag set by a previous instruction. If the given condition is true (ZF=0), a short jump is made to the location provided as the operand. Operation It Performs if (ZF == 0) { /* extend sign of label */ if (label < 0) displacement = 0xFF00 | label; else displacement = 0x00FF & label; /* branch to labeled instruction */ IP = IP + displacement; } Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Instruction Set 4-107 JNE JNE Examples This example subtracts an integer or an unsigned number in DX from another number of the same type in AX, and then uses the difference to determine the course of action. SUB and JNE implement a construct equivalent to a C-language if statement. ; branch according to the result of the integer or ; unsigned subtraction SUB JNE ... AX,DX DIFFERENCE ; are AX and DX the same? ; if not, then jump DIFFERENCE: ... Tips If you need to jump to an instruction at farlabel that is more than 128 bytes away, use the following sequence of statements: JE nearlabel JMP farlabel nearlabel: ; This does the equivalent of a long jump ; based on the JNE condition. Related Instructions 4-108 If you want to See Compare two components using subtraction and set the flags accordingly Jump if the result of a previous integer or unsigned comparison was equal CMP JE Jump unconditionally Set the flags according to whether particular bits of a component are set to 1 JMP TEST Instruction Set JNG Jump If Not Greater JNG Form Opcode Description Clocks Am186 Am188 JNG rel8 7E cb Jump short if not greater (ZF=1 or SF≠OF) 13,4 13,4 What It Does If the previous instruction sets the Zero Flag (ZF), or modifies the Sign Flag (SF) and the Overflow Flag (OF) so that they are not the same, JLE and JNG stop executing the current sequence of instructions and begin executing a new sequence of instructions; otherwise, execution continues with the next instruction. See JLE on page 4-97 for a complete description. Instruction Set 4-109 JNGE Jump If Not Greater or Equal JNGE Form Opcode Description Clocks Am186 Am188 JNGE rel8 7C cb Jump short if not greater or equal (SF≠OF) 13,4 13,4 What It Does If the previous instruction modifies the Sign Flag (SF) and the Overflow Flag (OF) so that they are not the same, JL and JNGE stop executing the current sequence of instructions and begin executing a new sequence of instructions; otherwise, execution continues with the next instruction. See JL on page 4-95 for a complete description. 4-110 Instruction Set JNL Jump If Not Less JNL Form Opcode Description Clocks Am186 Am188 JNL rel8 7D cb Jump short if not less (SF=OF) 13,4 13,4 What It Does If the previous instruction modifies the Sign Flag (SF) and the Overflow Flag (OF) so that they are the same, JGE and JNL stop executing the current sequence of instructions and begin executing a new sequence of instructions; otherwise, execution continues with the next instruction. See JGE on page 4-93 for a complete description. Instruction Set 4-111 JNLE Jump If Not Less or Equal JNLE Form Opcode Description Clocks Am186 Am188 JNLE rel8 7F cb Jump short if not less or equal (ZF=0 and SF=OF) 13,4 13,4 What It Does If the previous instruction clears the Zero Flag (ZF), and modifies the Sign Flag (SF) and the Overflow Flag (OF) so that they are the same, JG and JNLE stop executing the current sequence of instructions and begin executing a new sequence of instructions; otherwise, execution continues with the next instruction. See JG on page 4-91 for a complete description. 4-112 Instruction Set JNO Jump If Not Overflow JNO Form Opcode Description Clocks Am186 Am188 JNO rel8 71 cb Jump short if not overflow (OF=0) 13,4 13,4 What It Does If the previous instruction clears the Overflow Flag (OF), JNO stops executing the current sequence of instructions and begins executing a new sequence of instructions; otherwise, execution continues with the next instruction. Syntax To jump if the result of a previous operation cleared OF to 0, use JNO. JNO label Description JNO tests the flag set by a previous instruction. If the given condition is true (OF=0), a short jump is made to the location provided as the operand. Operation It Performs if (OF == 0) { /* extend sign of label */ if (label < 0) displacement = 0xFF00 | label; else displacement = 0x00FF & label; /* branch to labeled instruction */ IP = IP + displacement; } Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Instruction Set 4-113 JNO JNO Tips If you need to jump to an instruction at farlabel that is more than 128 bytes away, use the following sequence of statements: JO nearlabel JMP farlabel nearlabel: ; This does the equivalent of a long jump ; based on the JNO condition. Related Instructions 4-114 If you want to See Compare two components using subtraction and set the flags accordingly CMP Jump unconditionally JMP Jump if the result of a previous operation set OF to 1 Set the flags according to whether particular bits of a component are set to 1 JO TEST Instruction Set JNP Jump If Not Parity JNP Form Opcode Description Clocks Am186 Am188 JNP rel8 7B cb Jump short if not parity (PF=0) 13,4 13,4 What It Does If the previous instruction clears the Parity Flag (PF), JPO and JNP stop executing the current sequence of instructions and begin executing a new sequence of instructions; otherwise, execution continues with the next instruction. See JPO on page 4-124 for a complete description. Instruction Set 4-115 JNS Jump If Not Sign JNS Form Opcode Description Clocks Am186 Am188 JNS rel8 79 cb Jump short if not sign (SF=0) 13,4 13,4 What It Does If the previous instruction clears the Sign Flag (SF), JNS stops executing the current sequence of instructions and begins executing a new sequence of instructions; otherwise, execution continues with the next instruction. Syntax JNS label To jump if the result of a previous operation cleared SF to 0, use JNS. Description JNS tests the flag set by a previous instruction. If the given condition is true (SF=0), a short jump is made to the location provided as the operand. Operation It Performs if (SF == 0) { /* extend sign of label */ if (label < 0) displacement = 0xFF00 | label; else displacement = 0x00FF & label; /* branch to labeled instruction */ IP = IP + displacement; } Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF PF CF – – – – – res – res – res – 11 10 9 8 7 6 ? = undefined; – = unchanged 4-116 AF – Instruction Set 5 4 3 2 1 0 JNS JNS Tips If you need to jump to an instruction at farlabel that is more than 128 bytes away, use the following sequence of statements: JS nearlabel JMP farlabel nearlabel: ; This does the equivalent of a long jump ; based on the JNS condition. Related Instructions If you want to See Compare two components using subtraction and set the flags accordingly CMP Jump unconditionally JMP Jump if the result of a previous operation set SF to 1 Set the flags according to whether particular bits of a component are set to 1 JS TEST Instruction Set 4-117 JNZ Jump If Not Zero JNZ Form Opcode Description Clocks Am186 Am188 JNZ rel8 75 cb Jump short if not zero (ZF=0) 13,4 13,4 What It Does If the previous instruction clears the Zero Flag (ZF), JNE and JNZ stop executing the current sequence of instructions and begin executing a new sequence of instructions; otherwise, execution continues with the next instruction. See JNE on page 4-107 for a complete description. 4-118 Instruction Set JO Jump If Overflow JO Form Opcode Description Clocks Am186 Am188 JO rel8 70 cb Jump short if overflow (OF=1) 13,4 13,4 What It Does If the previous instruction sets the Overflow Flag (OF), JO stops executing the current sequence of instructions and begins executing a new sequence of instructions; otherwise, execution continues with the next instruction. Syntax JO label To jump if the result of a previous operation set OF to 1, use JO. Description JO tests the flag set by a previous instruction. If the given condition is true (OF=1), a short jump is made to the location provided as the operand. Operation It Performs if (OF == 1) { /* extend sign of label */ if (label < 0) displacement = 0xFF00 | label; else displacement = 0x00FF & label; /* branch to labeled instruction */ IP = IP + displacement; } Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Tips If you need to jump to an instruction at farlabel that is more than 128 bytes away, use the following sequence of statements: JNO nearlabel JMP farlabel nearlabel: ; This does the equivalent of a long jump ; based on the JO condition. Instruction Set 4-119 JO JO Related Instructions 4-120 If you want to See Compare two components using subtraction and set the flags accordingly Jump unconditionally CMP JMP Jump if the result of a previous operation cleared OF to 0 Set the flags according to whether particular bits of a component are set to 1 JNO TEST Instruction Set JP Jump If Parity JP Form Opcode Description Clocks Am186 Am188 JP rel8 7A cb Jump short if parity (PF=1) 13,4 13,4 What It Does If the previous instruction sets the Parity Flag (PF), JPE and JP stop executing the current sequence of instructions and begin executing a new sequence of instructions; otherwise, execution continues with the next instruction. See JPE on page 4-122 for a complete description. Instruction Set 4-121 JPE JP Jump If Parity Even Jump If Parity JPE Form Opcode Description Clocks Am186 Am188 JPE rel8 7A cb Jump short if parity even (PF=1) 13,4 13,4 JP rel8 7A cb Jump short if parity (PF=1) 13,4 13,4 What It Does If the previous instruction sets the Parity Flag (PF), JPE and JP stop executing the current sequence of instructions and begin executing a new sequence of instructions; otherwise, execution continues with the next instruction. Syntax JPE label JP label To jump if the result of a previous operation set PF to 1, use JPE or its synonym, JP. Both forms perform the same operation. Description JPE and JP test the flag set by a previous instruction. If the given condition is true (PF=1), a short jump is made to the location provided as the operand. Operation It Performs if (PF == 1) { /* extend sign of label */ if (label < 0) displacement = 0xFF00 | label; else displacement = 0x00FF & label; /* branch to labeled instruction */ IP = IP + displacement; } Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 ? = undefined; – = unchanged 4-122 AF Instruction Set 5 4 3 2 1 0 JPE JPE Tips If you need to jump to an instruction at farlabel that is more than 128 bytes away, use the following sequence of statements: JPO nearlabel JMP farlabel nearlabel: ; This does the equivalent of a long jump ; based on the JPE condition. Related Instructions If you want to See Compare two components using subtraction and set the flags accordingly CMP Jump unconditionally JMP Jump if the result of a previous operation cleared PF to 0 Set the flags according to whether particular bits of a component are set to 1 JPO TEST Instruction Set 4-123 JPO JNP Jump If Parity Odd Jump If Not Parity JPO Form Opcode Description Clocks Am186 Am188 JPO rel8 7B cb Jump short if parity odd (PF=0) 13,4 13,4 JNP rel8 7B cb Jump short if not parity (PF=0) 13,4 13,4 What It Does If the previous instruction clears the Parity Flag (PF), JPO and JNP stop executing the current sequence of instructions and begin executing a new sequence of instructions; otherwise, execution continues with the next instruction. Syntax JPO label JNP label To jump if the result of a previous operation cleared PF to 0, use JPO or its synonym, JNP. Both forms perform the same operation. Description JPO and JNP test the flag set by a previous instruction. If the given condition is true (PF=0), a short jump is made to the location provided as the operand. Operation It Performs if (PF == 0) { /* extend sign of label */ if (label < 0) displacement = 0xFF00 | label; else displacement = 0x00FF & label; /* branch to labeled instruction */ IP = IP + displacement; } Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 ? = undefined; – = unchanged 4-124 AF Instruction Set 5 4 3 2 1 0 JPO JPO Tips If you need to jump to an instruction at farlabel that is more than 128 bytes away, use the following sequence of statements: JPE nearlabel JMP farlabel nearlabel: ; This does the equivalent of a long jump ; based on the JPO condition. Related Instructions If you want to See Compare two components using subtraction and set the flags accordingly CMP Jump unconditionally JMP Jump if the result of a previous operation set PF to 1 Set the flags according to whether particular bits of a component are set to 1 JPE TEST Instruction Set 4-125 JS Jump If Sign JS Form Opcode Description Clocks Am186 Am188 JS rel8 78 cb Jump short if sign (SF=1) 13,4 13,4 What It Does If the previous instruction sets the Sign Flag (SF), JS stops executing the current sequence of instructions and begins executing a new sequence of instructions; otherwise, execution continues with the next instruction. Syntax JS label To jump if the result of a previous operation set SF to 1, use JS. Description JS tests the flag set by a previous instruction. If the given condition is true (SF=1), a short jump is made to the location provided as the operand. Operation It Performs if (SF == 1) { /* extend sign of label */ if (label < 0) displacement = 0xFF00 | label; else displacement = 0x00FF & label; /* branch to labeled instruction */ IP = IP + displacement; } Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF PF CF – – – – – res – res – res – 11 10 9 8 7 6 ? = undefined; – = unchanged 4-126 AF – Instruction Set 5 4 3 2 1 0 JS JS Tips If you need to jump to an instruction at farlabel that is more than 128 bytes away, use the following sequence of statements: JNS nearlabel JMP farlabel nearlabel: ; This does the equivalent of a long jump ; based on the JS condition. Related Instructions If you want to See Compare two components using subtraction and set the flags accordingly CMP Jump unconditionally JMP Jump if the result of a previous operation cleared SF to 0 Set the flags according to whether particular bits of a component are set to 1 JNS TEST Instruction Set 4-127 JZ Jump If Zero JZ Form Opcode Description Clocks Am186 Am188 JZ rel8 74 cb Jump short if 0 (ZF=1) 13,4 13,4 What It Does If the previous instruction sets the Zero Flag (ZF), JE and JZ stop executing the current sequence of instructions and begin executing a new sequence of instructions; otherwise, execution continues with the next instruction. See JE on page 4-89 for a complete description. 4-128 Instruction Set 4 LAHF Load AH with Flags LAHF Clocks Am186 Am188 Form Opcode Description LAHF 9F Load AH with low byte of Processor Status Flags register 2 2 What It Does LAHF copies the low byte of the Processor Status Flags (FLAGS) register to AH. Syntax LAHF Description LAHF copies the Processor Status Flags (FLAGS) register to the AH register. After the copy, the bits shadow the flags as follows: n AH bit 0 = Carry Flag n AH bit 2 = Parity Flag n AH bit 4 = Auxiliary Flag n AH bit 6 = Zero Flag n AH bit 7 = Sign Flag Operation It Performs /* copy FLAGS to AH */ AH = FLAGS & 0x00FF; Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Examples This example clears the Carry Flag (CF) to 0. Normally, you use CLC to perform this operation. ; clear CF to 0 LAHF AND AH,11111110b SAHF ; copy low byte of FLAGS to AH ; clear bit 0 (CF) to 0 ; copy AH to low byte of FLAGS Instruction Set 4-129 LAHF LAHF This example prevents an intervening instruction from modifying the Carry Flag (CF), which is used to indicate the status of a hardware device. SMINUEND SSUBTRAHEND DW DW -6726 22531 ; prevent subtraction from modifying CF, which is used ; as a device status indicator ; check to see if device is on or off ; return result in CF: 1 = on, 0 = off CALL CHECK_DEVICE ; set up registers MOV CX,SMINUEND MOV BX,SSUBTRAHEND ; CX = 1A46h ; BX = BD93h ; save lower five flags in AH LAHF ; unsigned subtraction: CX = CX - BX SUB CX,BX ; CF = 1 ; restore saved flags from AH SAHF ; CF = outcome of CHECK_DEVICE ; if device is on, then perform next action ; else, alert user to turn on device JC OKAY JMP ALERT_USER OKAY: ... ALERT_USER: ... Tips LAHF is provided for compatibility with the 8080 microprocessor. It is now customary to use PUSHF instead. Related Instructions 4-130 If you want to See Pop the top component from the stack into the Processor Status Flags register POPF Push the Processor Status Flags register onto the stack Copy AH to the low byte of the Processor Status Flags register PUSHF SAHF Instruction Set LDS Load DS with Segment and Register with Offset LDS Clocks Am186 Am188 Form Opcode Description LDS r16,m16:16 C5 /r Load DS:r16 with segment:offset from memory 18 26 What It Does LDS copies the segment portion of a full address stored in a doubleword to DS, and copies the offset portion of the full address to another register. Syntax LDS offset,pointer Description LDS reads a full pointer from memory and stores it in a register pair consisting of the DS register and a second operand-specified register. The first 16 bits are in DS and the remaining 16 bits are placed into the register specified by offset. Operation It Performs /* copy offset portion of pointer */ offset = pointer; /* copy segment portion of pointer */ DS = pointer + 2; Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Examples This example calls a procedure whose address is stored in a doubleword in memory. PROC_ADDR DD ? ; full address of current procedure ; store address of current procedure in PROC_ADDR ... LDS SI,PROC_ADDR ; load segment of procedure into DS ; and offset of procedure into SI ; call procedure at address stored in doubleword in memory CALL DWORD PTR [SI] Instruction Set 4-131 LDS LDS Related Instructions 4-132 If you want to See Load the offset of a memory component into a register Load a full address stored in a doubleword into ES and another register LEA LES Instruction Set LEA Load Effective Address LEA Clocks Am186 Am188 Form Opcode Description LEA r16,m16 8D /r Load offset for m16 word in 16-bit register 6 6 What It Does LEA loads the offset of a memory component into a register. Syntax LEA offset,component Description LEA calculates the effective address (offset part) of the component and stores it in the specified register. Operation It Performs /* copy offset of component */ offset = &component; Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Examples This example fills a string in memory with a character. Because the Direction Flag (DF) is cleared to 0 using CLD, the bytes are filled, one by one, from first to last. STRING ASTERISK DB DB 128 DUP (?) ’*’ ; 2Ah ; fill string with character ; set up registers and flags MOV AX,SEG STRING MOV ES,AX MOV AL,ASTERISK ; LEA DI,STRING ; MOV CX,LENGTH STRING ; CLD ; REP copy character to AL load offset (segment = ES) set up counter process string low to high ; fill string STOSB Instruction Set 4-133 LEA LEA Related Instructions 4-134 If you want to See Load a full address stored in a doubleword into DS and another register Load a full address stored in a doubleword into ES and another register LDS LES Instruction Set LEAVE* Leave High-Level Procedure LEAVE Clocks Am186 Am188 Form Opcode Description LEAVE C9 Destroy procedure stack frame 8 8 What It Does LEAVE removes the storage for the local variables of a procedure from the stack. Syntax LEAVE Description LEAVE destroys the stack frame created by ENTER. LEAVE releases the portion of the stack allocated for the procedure’s local variables by copying BP to SP, and then restores the calling procedure’s frame by popping its frame pointer into BP. Operation It Performs /* update stack and base pointers */ SP = BP; BP = pop(); Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged * – This instruction was not available on the original 8086/8088 systems. Instruction Set 4-135 LEAVE LEAVE Examples This example procedure uses ENTER to: push the current frame pointer (BP) onto the stack, set up BP to point to its stack frame, reserve 4 bytes on the stack for its local variables, and indicate that it is not called by another procedure. The procedure uses LEAVE to remove the local variables from the stack and restore BP. ; procedure that is not called by another Main PROC FAR ENTER 4,0 ; reserve 4 bytes for variables ; procedure is not called by another ; perform operations ... ; save AX PUSH AX ; perform operations ... LEAVE RET Main 4-136 2 ; remove variables from stack ; remove saved AX from stack ENDP Instruction Set LEAVE LEAVE This example includes two procedures, each of which uses ENTER to create its own stack frame. Each procedure uses LEAVE to destroy its stack frame before returning to the procedure that called it. ; top-level procedure Main PROC FAR ENTER 6,1 ; reserve 6 bytes for variables ; level 1 procedure ; perform operations ... Main LEAVE RET ENDP ; remove variables from stack ; second-level procedure Sub2 PROC FAR ENTER 20,2 ; reserve 20 bytes for variables ; level 2 procedure ; perform operations ... Sub2 LEAVE RET ENDP ; remove variables from stack Tips Before you use LEAVE, use MOV to copy the stack segment to SS and the stack offset to SP. If a procedure receives input parameters via the stack from the calling procedure, but it does not need to pass them back as output parameters, use RET components after LEAVE to return and pop the input parameters from the stack. Related Instructions If you want to See Reserve storage on the stack for the local variables of a procedure ENTER Instruction Set 4-137 LES Load ES with Segment and Register with Offset LES Clocks Am186 Am188 Form Opcode Description LES r16,m16:16 C4 /r Load ES:r16 with segment:offset from memory 18 26 What It Does LES copies the segment portion of a full address stored in a doubleword to ES, and copies the offset portion of the full address to another register. Syntax LES offset,pointer Description LES reads a full pointer from memory and stores it in a register pair consisting of the ES register and a second operand-specified register. The first 16 bits are in ES and the remaining 16 bits are placed into the register specified by offset. Operation It Performs /* copy offset portion of pointer */ offset = pointer; /* copy segment portion of pointer */ ES = pointer + 2; Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF PF CF – – – – – res – res – res – 11 10 9 8 7 6 ? = undefined; – = unchanged 4-138 AF – Instruction Set 5 4 3 2 1 0 LES LES Examples This example copies several of the characters in a string stored in memory to a series of bytes in the same string that overlap the original characters. The microcontroller copies the bytes, one by one, from last to first to avoid overwriting the source bytes. ; defined in SEG_1 segment STRING DB ”Am186EM*”,8 STRING_ADDR DD STRING ; NUMCHARS EQU 8 ; DELTA EQU 4 ; DUP (?); source and dest. full address of STRING copy eight characters 4 bytes away ; direct assembler that DS and ES point to ; different segments of memory ASSUME DS:SEG_1, ES:SEG_2 ; set up DS and ES with different segment addresses MOV AX,SEG_1 ; load one segment into DS MOV DS,AX ; DS points to SEG_1 MOV AX,SEG_2 ; load another segment into ES MOV ES,AX ; ES points to SEG_2 ; load source offset (segment = DS) ; SIZE and TYPE are assembler directives LEA SI,STRING + SIZE STRING - TYPE STRING ; load dest. segment (DS) into ES and offset into DI LES DI,ES(STRING+SIZE STRING-TYPE STRING-DELTA) MOV CX,NUMCHARS ; set up counter STD ; process string high to low REP ; copy eight bytes of string to destination within string MOVS STRING,ES:STRING Related Instructions If you want to See Load a full address stored in a doubleword into DS and another register Load the offset of a memory component into a register LDS LEA Instruction Set 4-139 LOCK* Lock the Bus LOCK Form Prefix to Opcode Description LOCK F0 Asserts LOCK during an instruction execution Clocks Am186 Am188 1 1 What It Does The LOCK prefix asserts the LOCK signal for the specified instruction to prevent an external master from requesting the bus. Syntax LOCK instr Description LOCK is a prefix for a single instruction. On 186 processors with a LOCK pin assignment, the LOCK pin is asserted for the duration of the prefixed instruction. The LOCK prefix may be combined with the segment override and/or REP prefix. Operation It Performs assert LOCK# execute(instruction) de-assert LOCK# Flag Settings After Instruction Instruction prefixes do not affect the flags. See the instruction being prefixed for the flag values. Tips The LOCK pin will assert for the entire repeated instruction. LOCK prevents DMA cycles until the entire LOCK instruction is complete (this includes a LOCK REP string instruction). LOCK prevents the processor from acknowledging a HOLD or taking an interrupt except for a nonmaskable interrupt. Related Instructions If you want to See Copy a component to a register or to a location in memory Repeatedly execute a single string instruction Exchange one component with another component MOV REP XCHG * – The external LOCK pin is only available on some members of the Am186 and Am188 family of microcontrollers. However, LOCK internal logic is still in effect on parts without the LOCK pin. 4-140 Instruction Set LODS Load String Component LODSB Load String Byte LODSW Load String Word LODS Clocks Am186 Am188 Form Opcode Description LODS m8 AC Load byte segment:[SI] in AL 12 12 LODS m16 AD Load word segment:[SI] in AX 12 16 LODSB AC Load byte DS:[SI] in AL 12 12 LODSW AD Load word DS:[SI] in AX 12 16 What It Does LODS copies a component from a string to a register. Syntax LODS source LODSB LODSW To override the default source segment (DS), and to have the assembler typecheck your operand, use this form. In this form, source is segment:[SI]. The assembler uses the segment in DS unless you specify a different segment register as part of the string component. The assembler uses the definition of the string component to determine Before using any form of LODS, which destination register to use. make sure that SI contains the offset of the string. To copy a byte within a string located in the segment specified in DS to AL, use this form. To copy a word within a string located in the segment specified in DS to AX, use this form. Description LODS loads the memory byte or word at the location pointed to by the source-index register into the AL or AX register. After the transfer, the instruction automatically advances the source-index register. If DF=0 (the CLD instruction was executed), the source index increments; if DF=1 (the STD instruction was executed), it decrements. The increment/decrement rate is 1 for a byte or 2 for a word. The source data address is determined solely by the contents of the source-index register; load the correct index value into the register before executing LODS. DS is the default source segment. LODSB and LODSW are synonyms for the byte and word LODS instructions, respectively. Instruction Set 4-141 LODS LODS Operation It Performs if (size(source) == 8) /* load bytes */ { AL = DS:[SI]; if (DF == 0) increment = 1; else increment = -1; } /* forward */ /* backward */ if (size(source) == 16) /* load words */ { AX = DS:[SI]; if (DF == 0) increment = 2; else increment = -2; } /* forward */ /* backward */ /* point to next string component */ SI = SI + increment; Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF PF CF – – – – – res – res – res – 11 10 9 8 7 6 ? = undefined; – = unchanged 4-142 AF – Instruction Set 5 4 3 2 1 0 LODS LODS Examples This example copies a string of 16-bit integers in one segment to a string in another segment. The microcontroller copies the words and changes their sign—one by one, from first to last—before storing them in the other string. Before setting up the registers for the string operation, this example exchanges DS for ES in order to address the destination string using ES. ; defined in SEG_S segment SOURCE DW 16 DUP (?) ; defined in SEG_D segment DESTINATION DW LENGTH SOURCE DUP (?) ; notify assembler: DS and ES specify different segments ASSUME DS:SEG_D, ES:SEG_S ; set up segment registers with different segments MOV AX,SEG_D ; load one segment into DS MOV DS,AX ; DS points to SEG_D, destination MOV AX,SEG_S ; load another segment into ES MOV ES,AX ; ES points to SEG_S, source ; initialize and use source string ... ; exchange DS for ES: the microcontroller ; you to override the segment register it ; the destination string (ES) PUSH ES ; ES points to PUSH DS ; DS points to POP ES ; ES points to POP DS ; DS points to ; set up registers and flags LEA SI,SOURCE ; LEA DI,DESTINATION ; MOV CX,LENGTH SOURCE ; ; CLD ; does not allow uses to address SEG_S, SEG_D, SEG_D, SEG_S, source destination destination source load source offset (segment = DS) load dest. offset (segment = ES) set up counter LENGTH is an assembler directive process string low to high LOAD: ; load integers, change their sign, and store them LODSW ; copy integer from source to AX NEG AX ; change sign of integer in AX STOSW ; copy integer from AX to dest. LOOP LOAD ; while CX is not zero, ; jump to top of loop ; exchange DS for ES PUSH ES PUSH DS POP ES POP DS ; ; ; ; ES DS ES DS Instruction Set points points points points to to to to SEG_D, SEG_S, SEG_S, SEG_D, destination source source destination 4-143 LODS LODS This example counts the number of carriage returns in a string of characters in memory. The microcontroller copies the bytes and compares them with the carriage-return character, one by one, from first to last. STRING CR DB DB 512 DUP (?) 0Dh ; carriage return ; count number of carriage returns in string ; initialize and use string ... ; set up registers and flags LEA SI,STRING MOV CX,LENGTH STRING CLD MOV DX,0 ; ; ; ; ; load offset (segment = DS) set up counter LENGTH is an assembler directive process string low to high set up total LOAD: ; load character and compare LODSB CMP AL,CR ; copy character to AL ; is it a carriage return? ; if not, then load next character JNE NEXT ; else, add 1 to number of carriage returns INC DX NEXT: LOOP LOAD ; while CX is not zero, ; jump to top of loop Tips Before using LODS, always be sure to: set up SI with the offset of the string, set up CX with the length of the string, and then use CLD (forward) or STD (backward) to establish the direction for string processing. To inspect each component in a string, use LODS within a loop. To perform a custom operation on each component in a string, use LODS and STOS within a loop. Within the loop, use the following sequence of instructions: use LODS to copy a component from memory, use other instructions to perform the custom operation, and then use STOS to copy the component back to memory. To overwrite the original string with the results, set up DI with the same offset as SI before beginning the loop. The string instructions always advance SI and/or DI, regardless of the use of the REP prefix. Be sure to set or clear DF before any string instruction. 4-144 Instruction Set LODS LODS Related Instructions If you want to See Process string components from lower to higher addresses Copy a component from a port in I/O memory to a string in main memory CLD INS Copy a component from one string to another string Copy a component from a string in main memory to a port in I/O memory MOVS OUTS Repeat one string instruction Process string components from higher to lower addresses REP STD Copy a component from a register to a string STOS Instruction Set 4-145 LOOP Loop While CX Register Is Not Zero LOOP Form Opcode Description Clocks Am186 Am188 LOOP rel8 E2 Decrement count; jump short if CX≠ 0 16,6 16,6 What It Does LOOP repeatedly executes a sequence of instructions; an unsigned number in CX tells the microcontroller how many times to execute the sequence. Syntax LOOP label Description At the bottom of a loop, LOOP subtracts 1 from CX, and then performs a short jump to the label at the top of the loop if CX is not 0. The label must be in the range from 128 bytes before LOOP to 127 bytes after LOOP. The microcontroller performs the following sequence of operations: 1. Executes the instructions between label and LOOP label. 2. Subtracts 1 from the unsigned number in CX. 3. Performs a short jump to the label if CX is not 0. When CX is 0, the microcontroller begins executing the instruction following LOOP. Operation It Performs /* decrement counter */ CX = CX - 1; if (CX != 0) { /* extend sign of label */ if (label < 0) displacement = 0xFF00 | label; else displacement = 0x00FF & label; /* loop */ IP = IP + displacement; } Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF PF CF – – – – – res – res – res – 11 10 9 8 7 6 ? = undefined; – = unchanged 4-146 AF – Instruction Set 5 4 3 2 1 0 LOOP LOOP Examples This example converts a list of unpacked decimal digits in memory to their ASCII equivalents. LIST L_LENGTH DB EQU 01h,08h,06h 3 ; convert a list of unpacked BCD digits to ASCII MOV MOV SI,0 CX,L_LENGTH ; point to first byte in list ; set up counter CONVERT: ; convert unpacked BCD digit to ASCII OR LIST[SI],30h INC SI ; point to next byte in list LOOP CONVERT ; while CX is not 0, jump to top of loop Related Instructions If you want to See Jump to another sequence of instructions if CX is 0 Jump unconditionally to another sequence of instructions JCXZ JMP Jump to the top of a loop if CX is not 0 and two compared components are equal LOOPE Jump to the top of a loop if CX is not 0 and two compared components are not equal LOOPNE Instruction Set 4-147 LOOPE Loop If Equal LOOPZ Loop If Zero LOOPE Form Opcode Description Clocks Am186 Am188 LOOPE rel8 E1 cb Decrement count; jump short if CX≠ 0 and ZF=1 16,6 16,6 LOOPZ rel8 E1 cb Decrement count; jump short if CX≠ 0 and ZF=1 16,6 16,6 What It Does LOOPE and LOOPZ repeatedly execute a sequence of instructions in which two components are compared; an unsigned number in CX tells the microcontroller the maximum number of times to execute the sequence. Once the microcontroller compares two components and finds they are not equal, the loop is no longer executed. Syntax LOOPE label LOOPZ label To repeat a loop until CX is 0 or two components compared inside the loop are not equal, use LOOPE or its synonym, LOOPZ. Both forms perform the same operation. Description At the bottom of a loop, LOOPE subtracts 1 from CX, and then performs a short jump to the label at the top of the loop if the following conditions are met: CX is not 0, and the two components that were just compared are equal. The label must be in the range from 128 bytes before LOOPE to 127 bytes after LOOPE. The microcontroller performs the following sequence of operations: 1. Executes the instructions between label and LOOPE label. 2. Subtracts 1 from the unsigned number in CX. 3. Performs a short jump to the label if CX is not 0 and the Zero Flag (ZF) is 1. When CX is 0 or ZF is 0, the microcontroller begins executing the instruction following LOOPE. LOOPZ is a synonym for LOOPE. Operation It Performs /* decrement counter */ CX = CX - 1; if ((CX != 0) && (ZF == 1)) /* equal */ { /* extend sign of label */ if (label < 0) displacement = 0xFF00 | label; else displacement = 0x00FF & label; /* loop */ IP = IP + displacement; } 4-148 Instruction Set LOOPE LOOPE Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Examples This example searches one row of a table in memory for a number other than 0. If the row contains a number other than 0, the microcontroller sets the Carry Flag (CF) to 1; otherwise, it sets CF to 0. ROW TABLE DW DW 8 DUP (?) 20 * (SIZE ROW) DUP (?) ; 20 x 8 table ; initialize and use table ... ; point to third row MOV BX,2 * (SIZE ROW) MOV SI,-2 MOV CX,LENGTH ROW ; SIZE ROW = 16 bytes ; set up row index ; set up counter SEARCH: ADD SI,2 CMP LOOPZ TABLE[BX][SI],0 SEARCH ; ; ; ; ; point to word in row (ADD before CMP to avoid changing flags) is word 0? while CX is not 0 (and word is 0), jump to top of loop ; if word is not 0, then jump JNE OTHER ; indicate that all words are 0 CLC JMP CONTINUE OTHER: STC ; indicate that at least one word is not 0 CONTINUE: ... Related Instructions If you want to See Jump to another sequence of instructions if CX is 0 Jump unconditionally to another sequence of instructions JCXZ JMP Jump to the top of a loop if CX is not 0 LOOP Jump to the top of a loop if CX is not 0 and two compared components are not equal LOOPNE Instruction Set 4-149 LOOPNE Loop If Not Equal LOOPNZ Loop If Not Zero LOOPNE Form Opcode Description Clocks Am186 Am188 LOOPNE rel8 E0 cb Decrement count; jump short if CX≠ 0 and ZF=0 16,6 16,6 LOOPNZ rel8 E0 cb Decrement count; jump short if CX≠ 0 and ZF=0 16,6 16,6 What It Does LOOPNE and LOOPNZ repeatedly execute a sequence of instructions in which two components are compared; an unsigned number in CX tells the microcontroller the maximum number of times to execute the sequence. Once the microcontroller compares two components and finds they are equal, the loop is no longer executed. Syntax LOOPNE label LOOPNZ label To repeat a loop until CX is 0 or two components compared inside the loop are equal, use LOOPNE or its synonym, LOOPNZ. Both forms perform the same operation. Description At the bottom of a loop, LOOPNE subtracts 1 from CX, and then performs a short jump to the label at the top of the loop if the following conditions are met: CX is not 0, and the two components that were just compared are not equal. The label must be in the range from 128 bytes before LOOPNE to 127 bytes after LOOPNE. The microcontroller performs the following sequence of operations: 1. Executes the instructions between label and LOOPNE label. 2. Subtracts 1 from the unsigned number in CX. 3. Performs a short jump to the label if CX is not 0 and the Zero Flag (ZF) is 0. When CX is 0 or ZF is 1, the microcontroller begins executing the instruction following LOOPNE. LOOPNZ is a synonym for LOOPNE. Operation It Performs /* decrement counter */ CX = CX - 1; if ((CX != 0) && (ZF == 0)) /* not equal */ { /* extend sign of label */ if (label < 0) displacement = 0xFF00 | label; else displacement = 0x00FF & label; /* loop */ IP = IP + displacement; } 4-150 Instruction Set LOOPNE LOOPNE Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Examples This example searches a list of characters stored in memory for a null character. If the list contains a null character, the microcontroller sets the Carry Flag (CF) to 1; otherwise, it sets CF to 0. CHARS NULL DB DB 128 DUP (?) 0 ; search a list for a null character ; initialize and use list ... ; set up registers MOV SI,-1 MOV CX,LENGTH CHARS ; set up list index ; set up counter SEARCH: INC SI CMP LOOPNE CHARS[SI],NULL SEARCH ; ; ; ; ; point to byte in list (INC before CMP to avoid changing flags) is byte a null? while CX is not 0 (and byte is not a null), jump to top of loop ; if byte is a null, then jump JE FOUND ; else, indicate that list doesn’t contain a null CLC JMP CONTINUE FOUND: STC ; indicate that list contains a null CONTINUE: ... Related Instructions If you want to See Jump to another sequence of instructions if CX is 0 Jump unconditionally to another sequence of instructions JCXZ JMP Jump to the top of a loop if CX is not 0 LOOP Jump to the top of a loop if CX is not 0 and two compared components are equal LOOPE Instruction Set 4-151 LOOPZ Loop If Zero LOOPZ Form Opcode Description Clocks Am186 Am188 LOOPZ rel8 E1 cb Decrement count; jump short if CX≠ 0 and ZF=1 16,6 16,6 What It Does LOOPE and LOOPZ repeatedly execute a sequence of instructions in which two components are compared; an unsigned number in CX tells the microcontroller the maximum number of times to execute the sequence. Once the microcontroller compares two components and finds they are not equal, the loop is no longer executed. See LOOPE on page 4-148 for a complete description. 4-152 Instruction Set MOV Move Component MOV Clocks Am186 Am188 Form Opcode Description MOV r/m8,r8 88 /r Copy register to r/m byte 2 2 MOV r/m16,r16 89 /r Copy register to r/m word 12 16 MOV r8,r/m8 8A /r Copy r/m byte to register 2 2 MOV r16,r/m16 8B /r Copy r/m word to register 9 13 MOV r/m16,sreg 8C /sr Copy segment register to r/m word 2/11 2/15 MOV sreg,r/m16 8E /sr Copy r/m word to segment register 2/9 2/13 MOV AL,moffs8 A0 Copy byte at segment:offset to AL 8 8 MOV AX,moffs16 A1 Copy word at segment:offset to AX 8 12 MOV moffs8,AL A2 Copy AL to byte at segment:offset 9 9 MOV moffs16,AX A3 Copy AX to word at segment:offset 9 13 MOV r8,imm8 B0+ rb Copy immediate byte to register 3 3 MOV r16,imm16 B8+ rw Copy immediate word to register 3 4 MOV r/m8,imm8 C6 /0 Copy immediate byte to r/m byte 12 12 MOV r/m16,imm16 C7 /0 Copy immediate word to r/m word 12 13 What It Does MOV copies a component to a register or to a location in memory. Syntax MOV copy,source Description MOV copies the second operand to the first operand. Operation It Performs /* copy component */ copy = source; Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Instruction Set 4-153 MOV MOV Examples This example defines and sets up the stack for a program. ; define stack segment SEG_STACK SEGMENT ’STACK’ DB 500 DUP (?) STACK: SEG_STACK ENDS ; set up stack (in code segment) MOV AX,SEG_STACK MOV SS,AX MOV AX,STACK MOV SP,AX ; ; ; ; load stack segment into SS SS points to SEG_STACK load stack offset into SP SP points to STACK This example for the SD186EM demonstration board controls the LEDs that are mapped (using negative logic) to eight of the microcontroller’s programmable input/output (PIO) pins according to the signal levels in AL. Because some of the LEDs on the board are mapped to the low eight PIO pins (5–0)—and some are mapped to the next eight PIO pins (15– 14)—the example duplicates the signal levels in AH. Before writing the PIO signal levels to the PIO Data 0 (PDATA0) register, the example uses NOT to convert them to negative logic. ; control LEDs mapped using negative logic ; load eight LED signal levels into AL ... ; write MOV MOV NOT OUT to LEDs DX,PIO_DATA0_ADDR AH,AL AX DX,AX ; ; ; ; address of PDATA0 register copy AL to AH LEDs are negative logic write out signals to port This example sets up the Data Segment (DS) register and the Extra Segment (ES) register with the same segment address. This is useful if you will be using MOVS to copy one string to another string stored in the same segment. If you set up DS and ES with different segment addresses, you must copy the value in one of them to the other—or override the source segment—before using MOVS. ; set up DS and ES with same segment address ; direct assembler that both DS and ES point to ; the same segment of memory ASSUME DS:SEG_C, ES:SEG_C ; set up DS and ES with SEG_C segment ; (can’t copy directly from memory location ; to segment register) MOV AX,SEG_C ; load same segment into DS and ES MOV DS,AX ; DS points to SEG_C MOV ES,AX ; ES points to SEG_C 4-154 Instruction Set MOV MOV This example sets up the Data Segment (DS) register and the Extra Segment (ES) register with different segment addresses. ; set up DS and ES with different segment addresses ; direct assembler that DS and ES point to ; different segments of memory ASSUME DS:SEG_A, ES:SEG_B ; set up DS with SEG_A segment and ES with SEG_B segment ; (can’t copy directly from memory location ; to segment register) MOV AX,SEG_A ; load one segment into DS MOV DS,AX ; DS points to SEG_A MOV AX,SEG_B ; load another segment into ES MOV ES,AX ; ES points to SEG_B Tips You cannot use MOV to copy directly from a memory location to a segment register. To copy a segment address to a segment register, first copy the segment address to a general register, and then copy the value in the general register to the segment register. Related Instructions If you want to See Copy a component from a port in I/O memory to a string in main memory Copy a component from one string in memory to another string in memory INS MOVS Copy a component from a string in main memory to a port in I/O memory OUTS Instruction Set 4-155 MOVS Move String Component MOVSB Move String Byte MOVSW Move String Word MOVS Clocks Am186 Am188 Form Opcode Description MOVS m8,m8 A4 Copy byte segment:[SI] to ES:[DI] 14 14 MOVS m16,m16 A5 Copy word segment:[SI] to ES:[DI] 14 18 MOVSB A4 Copy byte DS:[SI] to ES:[DI] 14 14 MOVSW A5 Copy word DS:[SI] to ES:[DI] 14 18 What It Does MOVS copies a component from one string to another string. Syntax MOVS destination,source MOVSB MOVSW To override the default source segment (DS) and to have the assembler typecheck your operands, use this form. In this form, source is segment:[SI]. The assembler uses the segment in DS unless you specify a different segment register as part of the source string component. The assembler uses the definitions of the string components to determine their sizes. To copy a byte within a string located in the source segment specified in DS to a byte within a string located in the destination segment specified in ES, use this form. Regardless of the form of MOVS you use, destination is always ES:[DI]. Before using any form of MOVS, make sure that ES contains the segment of the destination string, DI contains the offset of the destination string, and SI contains the offset of the source string. To copy a word within a string located in the source segment specified in DS to a word within a string located in the destination segment specified in ES, use this form. Description MOVS copies the byte or word at segment:[SI] to the byte or word at ES:[DI]. The destination operand must be addressable from the ES register; no segment override is possible for the destination. You can use a segment override for the source operand. The default is the DS register. The contents of SI and DI determine the source and destination addresses. Load the correct index values into the SI and DI registers before executing the MOVS instruction. After moving the data, MOVS advances the SI and DI registers automatically. If the Direction Flag (DF) is 0 (see STC on page 4-228), the registers increment. If DF is 1 (see STD on page 4-231), the registers decrement. The stepping is 1 for a byte, or 2 for a word operand. MOVSB and MOVSW are synonyms for the byte and word MOVS instructions, respectively. 4-156 Instruction Set MOVS MOVS Operation It Performs if (size(destination) == 8) /* copy bytes */ { ES:[DI] = DS:[SI]; if (DF == 0) increment = 1; else increment = -1; } /* forward */ /* backward */ if (size(destination) == 16) /* copy words */ { ES:[DI] = DS:[SI]; if (DF == 0) increment = 2; else increment = -2; } /* forward */ /* backward */ /* point to next string component */ DI = DI + increment; SI = SI + increment; Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Instruction Set 4-157 MOVS MOVS Examples This example copies several of the characters in a string stored in memory to a series of bytes in the same string that overlap the original characters. The microcontroller copies the bytes, one by one, from last to first to avoid overwriting the source bytes. ; defined in SEG_1 segment STRING DB ”Am186EM*”,8 STRING_ADDR DD STRING ; NUMCHARS EQU 8 ; DELTA EQU 4 ; DUP (?); source and dest. full address of STRING copy eight characters 4 bytes away ; direct assembler that DS and ES point to ; different segments of memory ASSUME DS:SEG_1, ES:SEG_2 ; set up DS and ES with different segment addresses MOV AX,SEG_1 ; load one segment into DS MOV DS,AX ; DS points to SEG_1 MOV AX,SEG_2 ; load another segment into ES MOV ES,AX ; ES points to SEG_2 PUSH ES ; save ES ; load source offset (segment = DS) LEA SI,STRING + SIZE STRING - TYPE STRING ; load dest. segment (DS) into ES and offset into DI LES DI,ES:STRING+SIZE ES:STRING-TYPE ES:STRING-DELTA MOV CX,NUMCHARS ; set up counter STD ; process string high to low REP ; copy eight bytes of string to destination within string MOVS STRING,ES:STRING POP 4-158 ES ; restore saved ES Instruction Set MOVS MOVS This example copies one string of 16-bit integers stored in memory to another string located in the same segment. Because the Direction Flag (DF) is cleared to 0 using CLD, the microcontroller copies the words, one by one, from first to last. ; defined in SEG_Z segment SOURCE DW 350,-4821,-276,449,10578 DEST DW 5 DUP (?) ; copy one string to another in the same segment ; direct assembler that DS and ES point to ; the same segment of memory ASSUME DS:SEG_Z, ES:SEG_Z ; set up DS and ES with same segment address MOV AX,SEG_Z ; load segment into DS and ES MOV DS,AX ; DS points to SEG_Z MOV ES,AX ; ES points to SEG_Z ; set up registers and flags LEA SI,SOURCE ; load source offset (segment = DS) LEA DI,DEST ; load dest. offset (segment = ES) MOV CX,5 ; set up counter CLD ; process string low to high REP ; copy source string to destination string MOVSW Tips Before using MOVS, always be sure to: set up SI with the offset of the source string and DI with the offset of the destination string, set up CX with the length of the strings, and use CLD (forward) or STD (backward) to establish the direction for string processing. To copy one string to another, use the REP prefix to execute MOVS repeatedly. To fill a string with a pattern, use MOV to: copy each component of the pattern to the first several components in the string, load SI with the offset of the string, load DI with the offset of the first component in the string that is not part of the pattern, load CX with the length of the string less the number of components in the pattern, and then use the REP prefix to execute MOVS repeatedly. The string instructions always advance SI and/or DI, regardless of the use of the REP prefix. Be sure to set or clear DF before any string instruction. Related Instructions If you want to See Process string components from lower to higher addresses CLD Copy a component from a port in I/O memory to a string in main memory Copy a component from a string in memory to a register INS LODS Copy a component from a string in main memory to a port in I/O memory Process string components from higher to lower addresses OUTS STD Copy a component from a register to a string in memory STOS Instruction Set 4-159 MUL Multiply Unsigned Numbers MUL Clocks Am186 Am188 Form Opcode Description MUL r/m8 F6 /4 AX=(r/m byte)•AL 26–28/32–34 26–28/32–34 MUL r/m16 F7 /4 DX::AX=(r/m word)•AX 35–37/41–43 35–37/45–47 What It Does MUL multiplies two unsigned numbers. Syntax mul multiplicand Description MUL operates on unsigned numbers. The operand you specify is the multiplicand. MUL assumes that the number by which it is to be multiplied (the multiplier) is in AL or AX. (MUL uses the multiplier that is the same size as the multiplicand.) MUL places the result in AX or DX::AX. (The destination is always twice the size of the multiplicand.) 4-160 Instruction Set MUL MUL Operation It Performs /* multiply multiplicand with accumulator */ if (size(multiplicand) == 8) /* unsigned byte multiplication */ { temp = multiplicand * AL; if (size(temp) == size(AL)) /* byte result */ { /* store result */ AL = temp; /* extend into AX */ AH = 0x00; /* clear overflow and carry flags */ OF = CF = 0; } else /* word result */ { /* store result */ AX = temp; /* set overflow and carry flags */ OF = CF = 1; } } if (size(multiplicand) == 16) /* unsigned word multiplication */ { temp = multiplicand * AX; if (size(temp) == size(AX)) /* word result */ { /* store result */ AX = temp; /* extend into DX */ DX = 0x00; /* clear overflow and carry flags */ OF = CF = 0; } else /* doubleword result */ { /* store result */ DX::AX = temp; /* set overflow and carry flags */ OF = CF = 1; } } Instruction Set 4-161 MUL MUL Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 11 IF TF SF ZF AF PF CF – – – ? ? res ? res ? res 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged OF and CF = 0 if upper half of result is 0 OF and CF = 1 otherwise Examples This example multiplies a 16-bit unsigned number in CX by a 16-bit unsigned number in AX. If the product is small enough to fit in only the low word of the destination, this example stores only the low word of the destination in memory. WPRODUCTH WPRODUCTL DW DW ? ? ; 16-bit unsigned multiplication: DX::AX = CX * AX MOV CX,32 MOV AX,300 MUL CX ; DX::AX = 00002580h = 9600 ; store low word of product MOV WPRODUCTL,AX ; if product fits in only low half of destination, then jump JNC CONTINUE ; ignore high half ; store high word of product MOV WPRODUCTH,DX CONTINUE: ... Tips Use SHL instead of MUL to multiply unsigned numbers by powers of 2. When multiplying an unsigned number by a power of 2, it is faster to use SHL than MUL. Much of the time, you can ignore the high half of the result because the product is small enough to fit in only the low half of the destination. If it is, MUL clears CF and OF to 0; otherwise, MUL sets CF and OF to 1. If the result will fit in a register that is the size of the multiplicand, and you either want to multiply an unsigned number by an immediate number or you don’t want the result to overwrite AL or AX, use the second and third forms of IMUL instead of MUL. Although designed for multiplying integers, these forms of IMUL calculate the same result as MUL while letting you specify more than one operand. Related Instructions 4-162 If you want to See Convert an 8-bit unsigned binary product to its unpacked decimal equivalent Multiply two integers AAM IMUL Multiply an unsigned number by a power of 2 SHL Instruction Set NEG Two’s Complement Negation NEG Form Opcode Description Clocks Am186 Am188 NEG r/m8 F6 /3 Perform a two’s complement negation of r/m byte 3/10 3/10 NEG r/m16 F7 /3 Perform a two’s complement negation of r/m word 3/10 3/14 What It Does NEG changes the sign of an integer. Syntax NEG integer 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. NEG sets CF if the operand is not zero. If the operand is zero, it is not changed and NEG clears CF. Operation It Performs if (integer == 0) /* clear carry flag */ CF = 0; else /* set carry flag CF = 1; /* change sign of integer */ integer = 0 - integer; Flag Settings After Instruction OF DF Processor Status Flags Register 15 14 13 12 11 IF TF SF ZF – – – 10 9 8 reserved AF res 7 6 5 PF res 4 3 CF res 2 1 0 ? = undefined; – = unchanged OF=1 if result larger than destination operand OF=0 otherwise SF=1 if result is 0 or positive SF=0 if result is negative ZF=1 if result equal to 0 ZF=0 if result not equal to 0 CF=1 if operand is not equal to 0 CF=0 if operand is equal to 0 PF=1 if low byte of result has even number of set bits PF=0 otherwise AF=1 if carry or borrow to low nibble AF=0 otherwise Instruction Set 4-163 NEG NEG Examples This example uses addition to find the difference between two integers. INTEGER1 INTEGER2 DW DW 2000 1600 ; 7D0h ; 640h ; calculate difference using sign change and addition NEG INTEGER2 ; INTEGER2 = F9C0h = -1600 ; signed addition: INTEGER1 = INTEGER1 + INTEGER2 ADD INTEGER1,INTEGER2 ; INTEGER1 = 0190h = 400 This example copies a string of 8-bit integers stored in memory to another string located in the same segment. The microcontroller copies the bytes and changes their sign—one by one, from first to last—before storing them in the other string. ; defined in SEG_C segment SOURCE DB 20 DUP (?) DESTINATION DB LENGTH SOURCE DUP (?) ; notify assembler: DS and ES point to the ; same segment of memory ASSUME DS:SEG_C, ES:SEG_C ; set up DS and ES with same segment address MOV AX,SEG_C ; load segment into DS and ES MOV DS,AX ; DS points to SEG_C MOV ES,AX ; ES points to SEG_C ; initialize and use source string ... ; save ES PUSH ES ; set up registers and flags LEA SI,SOURCE ; LEA DI,DESTINATION ; MOV CX,LENGTH SOURCE ; CLD ; load source offset (segment = DS) load dest. offset (segment = ES) set up counter process string low to high LOAD: LODSB NEG STOSB LOOP AL LOAD ; ; ; ; ; copy integer to AL change sign of integer in AL copy AL to destination string while CX is not zero, jump to top of loop ; restore ES POP ES Related Instructions 4-164 If you want to See Toggle all bits of a component NOT Subtract a number and the value of CF from another number Subtract a number from another number SBB SUB Instruction Set NOP No Operation NOP Clocks Am186 Am188 Form Opcode Description NOP 90 Perform no operation 3 3 What It Does NOP expends clock cycles exchanging AX with itself. Syntax NOP Description NOP performs no operation. It is a 1-byte instruction that takes up space in the code segment, but affects none of the machine context except the instruction pointer. Operation It Performs /* exchange AX with AX to pass time */ temp = AX; AX = AX; AX = temp; Flag Settings After Instruction OF DF Processor Status Flags Register 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 reserved 5 4 3 2 1 0 ? = undefined; – = unchanged Examples This example shows a delay loop. ; perform delay loop to insert real-time MOV AX,0FFFFh; set up counter LOOP1: ; waste time NOP NOP NOP NOP DEC AX JNZ LOOP1 ; subtract 1 from counter ; if AX is not 0, jump to top of loop Instruction Set 4-165 NOP NOP Tips Use NOP during a debugging session to fill code space left vacant after replacing an instruction with a shorter instruction. Related Instructions 4-166 If you want to See Suspend instruction execution HLT Instruction Set NOT One’s Complement Negation NOT Form Opcode Description Clocks Am186 Am188 NOT r/m8 F6 /2 Complement each bit in r/m byte 3/10 3/10 NOT r/m16 F7 /2 Complement each bit in r/m word 3/10 3/14 What It Does NOT toggles all bits of a component. Syntax NOT component Description NOT inverts the operand. Every 1 becomes a 0, and vice versa. NOT is equivalent to XOR with a mask of all 1s. Operation It Performs /* complement bits of component */ component = ~ component; Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Examples This example complements all bits of an 8-bit value in memory. The microcontroller changes each 0 to a 1 and each 1 to a 0. INDICATORS DB 11001010b ; complement indicators NOT INDICATORS ; INDICATORS = 00110101b Instruction Set 4-167 NOT NOT This example for the SD186EM demonstration board controls the LEDs that are mapped (using negative logic) to eight of the microcontroller’s programmable input/output (PIO) pins according to the signal levels in AL. Because some of the LEDs on the board are mapped to the low eight PIO pins (5–0)—and some are mapped to the next eight PIO pins (15– 14)—the example duplicates the signal levels in AH. Before writing the PIO signal levels to the PIO Data 0 (PDATA0) register, the example uses NOT to convert them to negative logic. ; control LEDs mapped using negative logic ; load eight LED signal levels into AL ... ; write MOV MOV NOT OUT to LEDs DX,PIO_DATA0_ADDR AH,AL AX DX,AX ; ; ; ; address of PDATA0 register copy AL to AH LEDs are negative logic write out signals to port Related Instructions 4-168 If you want to See Clear particular bits of a component to 0 Change the sign of an integer AND NEG Set particular bits of a component to 1 Toggle particular bits of a component OR XOR Instruction Set OR Logical Inclusive OR OR Clocks Am186 Am188 Form Opcode Description OR AL,imm8 0C ib OR immediate byte with AL 3 3 OR AX,imm16 0D iw OR immediate word with AX 4 4 OR r/m8,imm8 80 /1 ib OR immediate byte with r/m byte 4/16 4/16 OR r/m16,imm16 81 /1 iw OR immediate word with r/m word 4/16 4/20 OR r/m16,imm8 83 /1 ib OR immediate byte with r/m word 4/16 4/20 OR r/m8,r8 08 /r OR byte register with r/m byte 3/10 3/10 OR r/m16,r16 09 /r OR word register with r/m word 3/10 3/14 OR r8,r/m8 0A /r OR r/m byte with byte register 3/10 3/10 OR r16,r/m16 0B /r OR r/m word with word register 3/10 3/14 What It Does OR sets particular bits of a component to 1 according to a mask. Syntax OR component,mask 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. Operation It Performs /* OR component with mask */ component = component | mask; /* clear overflow and carry flags */ OF = CF = 0; Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF 0 – – – 11 10 9 8 AF PF res ? res 7 6 5 4 3 CF res 0 2 1 0 ? = undefined; – = unchanged SF=1 if result is 0 or positive SF=0 if result is negative ZF=1 if result equal to 0 ZF=0 if result not equal to 0 PF=1 if low byte of result has even number of set bits PF=0 otherwise Instruction Set 4-169 OR OR Examples This example converts an unpacked decimal digit to its ASCII equivalent. ASCII_MASK BCD_NUM EQU DB 30h 06h ; convert decimal number to ASCII MOV AL,BCD_NUM OR AL,ASCII_MASK ; decimal-to-ASCII mask ; 6 ; AL = 06h = 6 ; AL = 36h = ASCII ’6’ Tips To convert an unpacked decimal digit to its ASCII equivalent, use OR to add 30h (ASCII 0) to the digit. Related Instructions 4-170 If you want to See Clear particular bits of a component to 0 AND Toggle all bits of a component Toggle particular bits of a component NOT XOR Instruction Set OUT Output Component to Port OUT Clocks Am186 Am188 Form Opcode Description OUT imm8,AL E6 ib Output AL to immediate port 9 9 OUT imm8,AX E7 ib Output AX to immediate port 9 13 OUT DX,AL EE Output AL to port in DX 7 7 OUT DX,AX EF Output AX to port in DX 7 11 What It Does OUT copies a component from a register to a port in I/O memory. Syntax OUT port, source Description OUT transfers a data byte from the register (AL or AX) given as the second operand (source) to the output port numbered by the first operand (port). 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 the DX register as the first operand. If the instruction contains an 8-bit port number, that value is zero-extended to 16 bits. Operation It Performs /* extend port number */ if (size(port) == 8) port = 0x00FF & port; /* move component */ [port] = source; Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Instruction Set 4-171 OUT OUT Examples This example for the SD186EM demonstration board lights all of the LEDs that are mapped to eight of the PIO pins on the microcontroller. ; assert PIO pins 15-14 and 5-0 ; set up PIO pins 15-0 as outputs MOV DX,PIO_DIR0_ADDR ; address of PDIR0 register MOV AX,0 ; 0 = output OUT DX,AX ; write directions to register ; PIO pins 15-0 will be asserted MOV DX,PIO_DATA0_ADDR ; address of PDATA0 register MOV AX,0FFFFh ; 1 = high OUT DX,AX ; write levels to register ; only enable PIOs 15-14 and 5-0, the other PIO pins ; will perform their preassigned functions MOV DX,PIO_MODE0_ADDR ; address of PIOMODE0 register MOV AX,0C07Fh ; PIOs 15-14 and 5-0 OUT DX,AX ; write modes to register This example sets the baud rate divisor for the asynchronous serial port on the Am186EM controller. ; set baud rate divisor for asynchronous serial port MOV MOV OUT DX,SPRT_BDV_ADDR AX,129 DX,AX ; address of SPBAUD register ; 9600 baud at 40 MHz ; write out baud rate to register Tips Use OUT to talk to the peripheral registers, since they are initially set to I/O space (and not memory-mapped). Related Instructions 4-172 If you want to See Copy a component from a port in I/O memory to a register IN Copy a component from a port in I/O memory to a string in main memory Copy a component from a string in main memory to a port in I/O memory INS OUTS Instruction Set OUTS* Output String Component to Port OUTSB Output String Byte to Port OUTSW Output String Word to Port OUTS Clocks Am186 Am188 Form Opcode Description OUTS DX,m8 6E Output byte DS:[SI] to port in DX 14 14 OUTS DX,m16 6F Output word DS:[SI] to port in DX 14 14 OUTSB 6E Output byte DS:[SI] to port in DX 14 14 OUTSW 6F Output word DS:[SI] to port in DX 14 14 What It Does OUTS copies a component from a string in main memory to a port in I/O memory. Syntax OUTS port,source OUTSB OUTSW To have the assembler type-check your operands, use this form. The assembler uses the definition of the string component to determine its size. To copy a byte from within a string located in the segment specified in DS to the I/O port specified in DX, use this form. To copy a word from within a string located in the segment specified in DS to the I/O port specified in DX, use this form. Regardless of the form of OUTS you use, source is always DS:[SI], and port is always DX. Before using any form of OUTS, make sure that DS contains the segment of the string, SI contains the offset of the string, and DX contains the number of the port. Description OUTS transfers data from the address indicated by the source-index register (SI) to the output port addressed by the DX register. OUTS does not allow specification of the port number as an immediate value. You must address the port through the DX register value. Load the correct values into the DX register and the source-index (SI) register before executing the OUTS instruction. After the transfer, the source-index register advances automatically. If the Direction Flag (DF) is 0 (see CLD on page 4-29), the source-index register increments. If DF is 1 (see STD on page 4-231), it decrements. The SI register increments or decrements by 1 for a byte or 2 for a word. OUTSB and OUTSW are synonyms for the byte and word OUTS instructions. You can use the REP prefix with the OUTS instruction for block output of CX bytes or words. * – This instruction was not available on the original 8086/8088 systems. Instruction Set 4-173 OUTS OUTS Operation It Performs if (size(source) == 8) /* output bytes */ { [DX] = DS:[SI]; if (DF == 0) increment = 1; else increment = -1; } /* forward */ /* backward */ if (size(source) == 16) /* output words */ { [DX] = DS:[SI]; if (DF == 0) increment = 2; else increment = -2; } /* forward */ /* backward */ /* point to location for next string component */ SI = SI + increment; Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Tips Before using OUTS, always be sure to: set up SI with the offset of the string, set up CX with the length of the string, and use CLD (forward) or STD (backward) to establish the direction for string processing. The string instructions always advance SI and/or DI, regardless of the use of the REP prefix. Be sure to set or clear DF before any string instruction. Related Instructions If you want to See Process string components from lower to higher addresses Copy a component from a port in I/O memory to a register CLD IN Copy a component from a port in I/O memory to a string located in main memory INS Copy a component from a register to a port in I/O memory OUT Repeat one string instruction Process string components from higher to lower addresses 4-174 Instruction Set REP STD 4 POP Pop Component from Stack POP Clocks Am186 Am188 Form Opcode Description POP m16 8F /0 Pop top word of stack into memory word 20 24 POP r16 58+ rw Pop top word of stack into word register 10 14 POP DS 1F Pop top word of stack into DS 8 12 POP ES 07 Pop top word of stack into ES 8 12 POP SS 17 Pop top word of stack into SS 8 12 What It Does POP copies a component from the top of the stack and then removes the storage space for the component from the stack. Syntax POP component Description POP loads the word at the top of the processor stack into the destination specified by the operand. The top of the stack is specified by the contents of SS and the Stack Pointer register, SP. The stack pointer increments by 2 to point to the new top of stack. A POP SS instruction inhibits all interrupts, including nonmaskable interrupts, until after execution of the next instruction. This allows sequential execution of POP SS and POP SP instructions without danger of having an invalid stack during an interrupt. A pop-to-memory instruction that uses the stack pointer as a base register references memory after the POP. The base is the value of the stack pointer after the instruction has been executed. Note that POP CS is not a valid instruction; use RET to pop from the stack into CS. Operation It Performs /* copy component from stack */ destination = SS:[SP]; /* remove storage from stack */ SP = SP + 2; Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Instruction Set 4-175 POP POP Examples This example copies a string of 16-bit integers in one segment of memory to a string in another segment. The words are copied, one by one, from last to first. ; defined in SEG_A STRING1 DW S1_LENGTH EQU 5 ; defined in SEG_B STRING2 DW S2_END_ADDR DD -30000,10250,31450,21540,-16180 S1_LENGTH DUP (?) STRING2 + SIZE STRING2 - TYPE STRING2 ; notify assembler: DS and ES specify ; different segments of memory ASSUME DS:SEG_A, ES:SEG_B ; set up segment registers with different segments MOV AX,SEG_A ; load one segment into DS MOV DS,AX ; DS points to SEG_A MOV AX,SEG_B ; load another segment into ES MOV ES,AX ; ES points to SEG_B ; copy string in segment A to string in segment B ; save ES PUSH ES ; set up registers and flags LEA SI,STRING1 ; load source offset (segment = DS) ; load dest. segment into ES and offset into DI LES DI,ES:S2_END_ADDR MOV CX,S1_LENGTH ; set up counter STD ; process string high to low REP ; copy source string to destination MOVSW ; restore saved ES POP ES 4-176 Instruction Set POP POP This example procedure for the SD186EM demonstration board turns an LED on or off by toggling the signal level of programmable I/O (PIO) pin 3 in the PIO Data 0 (PDATA0) register. PIO3_MASK EQU ; toggle PDATA0 bit 3 TOGGLE_PIO3 PROC 0008h ; PDATA0 bit 3 NEAR ; save registers PUSH AX PUSH DX MOV IN XOR OUT DX,PIO_DATA0_ADDR AX,DX AX,PIO3_MASK DX,AX ; ; ; ; address of PDATA0 register read PDATA0 into AX toggle bit 3 write AX to PDATA0 ; restore saved registers POP DX POP AX RET TOGGLE_PIO3ENDP Tips Before you use POP, use MOV to copy the stack segment to SS and the stack offset to SP. Before you can pop a component from the stack, you must push one onto the stack. To copy one segment register to another, use PUSH to place the contents of the first segment register on the stack, and then use POP to load the other segment register. Use the stack to pass parameters from one procedure to another. In the calling procedure, use PUSH to push the parameters onto the stack, use CALL to call another procedure, and then use POP to pop the parameters from the stack. Use PUSH to temporarily save the intermediate results of a multistep calculation. Use PUSH to save the value of a register you want to temporarily use for another purpose. Use POP to restore the saved register value when you are done. Related Instructions If you want to See Pop components from the stack into the 16-bit general registers Pop a component from the stack into the Processor Status Flags register POPA POPF Push a component onto the stack PUSH Instruction Set 4-177 POPA* Pop All 16-Bit General Registers from Stack POPA Clocks Am186 Am188 Form Opcode Description POPA 61 Pop DI, SI, BP, BX, DX, CX, and AX 51 83 What It Does POPA copies each of eight components from the top of the stack to one of the 16-bit general registers and then removes the storage space for the components from the stack. Syntax POPA Description POPA pops the eight 16-bit general registers, but it discards the SP value instead of loading it into the SP register. POPA reverses a previous PUSHA, restoring the general registers to their values before the PUSHA instruction was executed. POPA pops the DI register first. Operation It Performs /* DI SI BP pop 16-bit general registers from stack */ = pop(); = pop(); = pop(); /* skip stack pointer */ SP = SP + 2; /* BX DX CX AX continue popping */ = pop(); = pop(); = pop(); = pop(); Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF PF CF – – – – – res – res – res – 11 10 9 8 7 6 ? = undefined; – = unchanged * – This instruction was not available on the original 8086/8088 systems. 4-178 AF – Instruction Set 5 4 3 2 1 0 POPA POPA Examples This example of an interrupt-service routine enables interrupts so that interrupt nesting can occur, resets a device, disables interrupts until the interrupted procedure is resumed, and then clears the in-service bits in the In-Service (INSERV) register by writing to the End-OfInterrupt (EOI) register. ; the microcontroller pushes the flags onto ; the stack before executing this routine ; enable interrupt nesting during routine ISR1 PROC FAR PUSHA STI ; save general registers ; enable unmasked maskable interrupts mRESET_DEVICE1 CLI ; perform operation (macro) ; disable maskable interrupts until IRET ; reset MOV MOV OUT in-service bits by writing to EOI register DX,INT_EOI_ADDR ; address of EOI register AX,8000h ; nonspecific EOI DX,AX ; write to EOI register POPA IRET ISR1 ; restore general registers ENDP ; the microcontroller pops the flags from the stack ; before returning to the interrupted procedure Tips Before you use POPA, use MOV to copy the stack segment to SS and the stack offset to SP. To prevent a called procedure from destroying register values that are necessary for the successful execution of the calling procedure, use PUSHA at the beginning of each procedure, and then use POPA at the end. If you want to pass a parameter to the calling procedure using a general register, copy the parameter to the register after POPA. Related Instructions If you want to See Pop a component from the stack Pop a component from the stack into the Processor Status Flags register POP POPF Push the 16-bit general registers onto the stack PUSHA Instruction Set 4-179 POPF Pop Flags from Stack POPF Clocks Am186 Am188 Form Opcode Description POPF 9D Pop top word of stack into Processor Status Flags register 8 12 What It Does POPF copies a component from the top of the stack, loads it into the Processor Status Flags (FLAGS) register, and then removes the storage space for the component from the stack. Syntax POPF Description POPF pops a word from the top of the stack and stores the value in the FLAGS register. Operation It Performs /* copy flags from stack */ FLAGS = SS:[SP]; /* delete storage from stack */ SP = SP + 2; Flag Settings After Instruction Processor Status Flags Register OF DF IF TF SF ZF 11 9 res reserved 15 14 13 AF 12 10 8 7 6 5 PF res 4 3 CF res 2 1 0 ? = undefined; – = unchanged Values in word at top of stack are copied into FLAGS register bits. Tips Before you use POPF, use MOV to copy the stack segment to SS and the stack offset to SP. To prevent an instruction or a called procedure from modifying flags that are necessary for the successful execution of the following instructions or calling procedure, use PUSHF to save the Processor Status Flags register. After the instruction or the procedure CALL, use POPF to restore the saved flags. Related Instructions 4-180 If you want to See Pop a component from the stack POP Pop components from the stack into the 16-bit general registers Push the Processor Status Flags register onto the stack POPA PUSHF Copy AH to the low byte of the Processor Status Flags register SAHF Instruction Set PUSH* Push Component onto Stack PUSH Clocks Am186 Am188 Form Opcode Description PUSH m16 FF /6 Push memory word onto stack 16 20 PUSH r16 50+ rw Push register word onto stack 10 14 PUSH imm8 6A Push sign-extended immediate byte onto stack 10 14 PUSH imm16 68 Push immediate word onto stack 10 14 PUSH CS 0E Push CS onto stack 9 13 PUSH SS 16 Push SS onto stack 9 13 PUSH DS 1E Push DS onto stack 9 13 PUSH ES 06 Push ES onto stack 9 13 What It Does PUSH creates storage space for a component on the stack and then copies the component to the stack. Syntax PUSH component Description PUSH decrements the stack pointer by 2. Then PUSH places the operand on the new stack top, indicated by the stack pointer. Operation It Performs /* create storage on stack */ SP = SP - 2; /* copy component to stack */ SS:[SP] = source; Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged * – PUSH immediates were not available on the original 8086/8088 systems. Instruction Set 4-181 PUSH PUSH Examples This example copies a string of 16-bit integers in one segment to a string in another segment. The microcontroller copies the words and changes their sign—one by one, from first to last—before storing them in the other string. Before setting up the registers for the string operation, this example exchanges DS for ES in order to address the destination string using ES. ; defined in SEG_S segment SOURCE DW 16 DUP (?) ; defined in SEG_D segment DESTINATIONDW LENGTH SOURCE DUP (?) ; notify assembler: DS and ES specify different segments ASSUME DS:SEG_D, ES:SEG_S ; set up segment registers with different segments MOV AX,SEG_D ; load one segment into DS MOV DS,AX ; DS points to SEG_D, destination MOV AX,SEG_S ; load another segment into ES MOV ES,AX ; ES points to SEG_S, source ; initialize and use source string ... ; exchange DS for ES: the microcontroller ; you to override the segment register it ; the destination string (ES) PUSH ES ; ES points to PUSH DS ; DS points to POP ES ; ES points to POP DS ; DS points to ; set up registers and flags LEA SI,SOURCE ; LEA DI,DESTINATION ; MOV CX,LENGTH SOURCE ; CLD ; does not allow uses to address SEG_S, SEG_D, SEG_D, SEG_S, source destination destination source load source offset (segment = DS) load dest. offset (segment = ES) set up counter process string low to high LOAD: ; load integers, change their sign, and store them LODSW ; copy integer from source to AX NEG AX ; change sign of integer in AX STOSW ; copy integer from AX to dest. LOOP LOAD ; while CX is not zero, ; jump to top of loop ; exchange DS for ES PUSH ES PUSH DS POP ES POP DS 4-182 ; ; ; ; ES DS ES DS Instruction Set points points points points to to to to SEG_D, SEG_S, SEG_S, SEG_D, destination source source destination PUSH PUSH This example procedure turns an LED on or off by toggling the signal level of programmable I/O (PIO) pin 3 in the PIO Data 0 (PDATA0) register. PIO3_MASK EQU ; toggle PDATA0 bit 3 TOGGLE_PIO3 PROC 0008h ; PDATA0 bit 3 NEAR ; save registers PUSH AX PUSH DX MOV IN XOR OUT DX,PIO_DATA0_ADDR AX,DX AX,PIO3_MASK DX,AX ; ; ; ; address of PDATA0 register read PDATA0 into AX toggle bit 3 write AX to PDATA0 ; restore saved registers POP DX POP AX RET TOGGLE_PIO3 ENDP Tips Before you use PUSH, use MOV to copy the stack segment to SS and the stack offset to SP. You must push a component onto the stack before you can pop one from the stack. To copy one segment register to another, use PUSH to place the contents of the first segment register on the stack, and then use POP to load the other segment register. Use the stack to pass parameters from one procedure to another. In the calling procedure, use PUSH to push the parameters onto the stack, use CALL to call another procedure, and then use POP to pop the parameters from the stack. Use PUSH to temporarily save the intermediate results of a multistep calculation. Use PUSH to save the value of a register you want to temporarily use for another purpose. Use POP to restore the saved register value when you are done. Related Instructions If you want to See Pop a component from the stack POP Push the 16-bit general registers onto the stack Push the Processor Status Flags register onto the stack PUSHA PUSHF Instruction Set 4-183 PUSHA* Push All 16-Bit General Registers onto Stack PUSHA Clocks Am186 Am188 Form Opcode Description PUSHA 60 Push AX, CX, DX, BX, original SP, BP, SI, and DI 36 68 What It Does PUSHA creates storage space for eight components on the stack and then copies each of the eight 16-bit general registers to the stack. Syntax PUSHA Description PUSHA saves the 16-bit general registers on the processor stack. PUSHA decrements the stack pointer (SP) by 16 to accommodate the required 8-word field. Because the registers are pushed onto the stack in the order in which they were given, they appear in the 16 new stack bytes in reverse order. The last register pushed is the DI register. Operation It Performs /* save stack pointer */ temp = SP; /* push 16-bit general registers onto stack */ push(AX); push(CX); push(DX); push(BX); /* push stack pointer */ push(temp); /* continue pushing */ push(BP); push(SI); push(DI); Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF PF CF – – – – – res – res – res – 11 10 9 8 7 6 ? = undefined; – = unchanged * – This instruction was not available on the original 8086/8088 systems. 4-184 AF – Instruction Set 5 4 3 2 1 0 PUSHA PUSHA Examples This example of an interrupt-service routine enables interrupts so that interrupt nesting can occur, resets a device, disables interrupts until the interrupted procedure is resumed, and then clears the in-service bits in the In-Service (INSERV) register by writing to the End-OfInterrupt (EOI) register. ; the microcontroller pushes the flags onto ; the stack before executing this routine ; enable interrupt nesting during routine ISR1 PROC FAR PUSHA STI ; save general registers ; enable unmasked maskable interrupts mRESET_DEVICE1 CLI ; perform operation (macro) ; disable maskable interrupts until IRET ; reset MOV MOV OUT in-service bits by writing to EOI register DX,INT_EOI_ADDR ; address of EOI register AX,8000h ; nonspecific EOI DX,AX ; write to EOI register POPA IRET ISR1 ; restore general registers ENDP ; the microcontroller pops the flags from the stack ; before returning to the interrupted procedure Tips Before you use PUSHA, use MOV to copy the stack segment to SS and the stack offset to SP. To prevent a called procedure from destroying register values that are necessary for the successful execution of the calling procedure, use PUSHA at the beginning of each procedure, and then use POPA at the end. If you want to pass a parameter to the calling procedure using a general register, copy the parameter to the register after POPA. Related Instructions If you want to See Pop components from the stack into the 16-bit general registers POPA Push a component onto the stack Push the Processor Status Flags register onto the stack PUSH PUSHF Instruction Set 4-185 PUSHF Push Flags onto Stack PUSHF Clocks Am186 Am188 Form Opcode Description PUSHF 9C Push Processor Status Flags register 9 13 What It Does PUSHF creates storage space for a component on the stack and then copies the Processor Status Flags (FLAGS) register to the stack. Syntax PUSHF Description PUSHF decrements the stack pointer by 2 and copies the FLAGS register to the new top of stack. Operation It Performs /* create storage on stack */ SP = SP - 2; /copy flags to stack */ SS:[SP] = FLAGS; Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Tips Before you use PUSHF, use MOV to copy the stack segment to SS and the stack offset to SP. To prevent an instruction or a called procedure from modifying flags that are necessary for the successful execution of the following instructions or calling procedure, use PUSHF to save the Processor Status Flags register. After the instruction or the procedure call, use POPF to restore the saved flags. Related Instructions 4-186 If you want to See Copy the low byte of the Processor Status Flags register to AH Pop a component from the stack into the Processor Status Flags register LAHF POPF Push a component onto the stack Push the 16-bit general registers onto the stack PUSH PUSHA Instruction Set RCL* Rotate through Carry Left RCL Form Opcode Description Clocks Am186 Am188 RCL r/m8,1 D0 /2 Rotate 9 bits of CF and r/m byte left once 2/15 2/15 RCL r/m8,CL D2 /2 Rotate 9 bits of CF and r/m byte left CL times 5+ n/17+ n 5+ n/17+ n RCL r/m8,imm8 C0 /2 ib Rotate 9 bits of CF and r/m byte left imm8 times 5+ n/17+ n 5+ n/17+ n RCL r/m16,1 D1 /2 Rotate 17 bits of CF and r/m word left once 2/15 2/15 RCL r/m16,CL D3 /2 Rotate 17 bits of CF and r/m word left CL times 5+ n/17+ n 5+ n/17+ n RCL r/m16,imm8 C1 /2 ib Rotate 17 bits of CF and r/m word left imm8 times 5+ n/17+ n 5+ n/17+ n What It Does RCL shifts the bits of a component to the left, copies the Carry Flag (CF) to the lowest bit of the component, and then overwrites CF with the bit shifted out of the component. Syntax RCL component,count Description RCL shifts CF into the bottom bit and shifts the top bit into CF. The second operand (count) indicates the number of rotations. The operand is either an immediate number or the CL register contents. The microcontroller does not allow rotation counts greater than 31. If the count is greater than 31, only the bottom 5 bits of the operand are rotated. Operation It Performs while (i = count; i != 0; i--) /* perform shifts */ { /* save highest bit */ temp = mostSignificantBit(component); /* shift left and fill vacancy with carry flag */ component = (component << 1) + CF; /* replace carry flag with saved bit */ CF = temp; } if (count == 1) /* single shift */ if (mostSignificantBit(component) != CF) /* set overflow flag */ OF = 1; else /* clear overflow flag */ OF = 0; * – Rotate immediates were not available on the original 8086/8088 systems. Instruction Set 4-187 RCL RCL Flag Settings After Instruction If count=0, flags are unaffected. Otherwise, flags are affected as shown below: OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF ? – – – – – res – res – res 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Undefined unless single-bit rotation, then: OF=1 if result larger than destination operand OF=0 otherwise CF=value of bit shifted into it Examples This example rotates the bits of a word in memory, maintaining a 1 in the low bit of the word. BITS DW 0100100010001001b; 4889h ; rotate word, maintaining 1 in low bit STC ; maintain 1 in low bit: CF = 1 RCL BITS,1 ; BITS = 9113h = 1001000100010011b ; CF = 0 Tips Use RCL to change the order of the bits within a component and the value of one of the bits. Related Instructions 4-188 If you want to See Clear CF to 0 Toggle the value of CF CLC CMC Rotate the bits of a component and the value of CF to the right Rotate the bits of a component to the left RCR ROL Rotate the bits of a component to the right Multiply an integer by a power of 2 ROR SAL/SHL Divide an integer by a power of 2 Shift the bits of the operand downward SAR SHR Set CF to 1 STC Instruction Set RCR* Rotate through Carry Right RCR Form Opcode Description Clocks Am186 Am188 RCR r/m8,1 D0 /3 Rotate 9 bits of CF and r/m byte right once 2/15 2/15 RCR r/m8,CL D2 /3 Rotate 9 bits of CF and r/m byte right CL times 5+ n/17+ n 5+ n/17+ n RCR r/m8,imm8 C0 /3 ib Rotate 9 bits of CF and r/m byte right imm8 times 5+ n/17+ n 5+ n/17+ n RCR r/m16,1 D1 /3 Rotate 17 bits of CF and r/m word right once 2/15 2/15 RCR r/m16,CL D3 /3 Rotate 17 bits of CF and r/m word right CL times 5+ n/17+ n 5+ n/17+ n RCR r/m16,imm8 C1 /3 ib Rotate 17 bits of CF and r/m word right imm8 times 5+ n/17+ n 5+ n/17+ n What It Does RCR shifts the bits of a component to the right, copies the Carry Flag (CF) to the highest bit of the component, and then overwrites CF with the bit shifted out of the component. Syntax RCR component,count Description RCR shifts CF into the top bit and shifts the bottom bit into CF. The second operand (count) indicates the number of rotations. The operand is either an immediate number or the CL register contents. The microcontroller does not allow rotation counts greater than 31. If the count is greater than 31, only the bottom 5 bits of the operand are rotated. Operation It Performs while (i = count; i != 0; i--) /* perform shifts */ { /* save lowest bit */ temp = leastSignificantBit(component); /* shift right and fill vacancy with carry flag */ component = (component >> 1) + (CF * pow(2, size(component) - 1)); /* replace carry flag with saved bit */ CF = temp; } if (count == 1) /* single shift */ if (mostSignificantBit(component) != nextMostSignificantBit(component)) /* set overflow flag */ OF = 1; else /* clear overflow flag */ OF = 0; * – Rotate immediates were not available on the original 8086/8088 systems. Instruction Set 4-189 RCR RCR Flag Settings After Instruction If count=0, flags are unaffected. Otherwise, flags are affected as shown below: OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF ? – – – – – res – res – res 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Undefined unless single-bit rotation, then: OF=1 if result larger than destination operand OF=0 otherwise CF=value of bit shifted into it Examples This example rotates the bits of a byte to the left, making sure that the high bit remains 0. ; rotate byte, maintaining 0 in high bit MOV AL,01101011b ; AL = 01101011b CLC ; CF = 0 RCR AL,1 ; AL = 00110101b, CF = 1 Tips Use RCR to change the order of the bits within a component and the value of one of the bits. Related Instructions 4-190 If you want to See Clear CF to 0 CLC Toggle the value of CF CMC Rotate the bits of a component and the value of CF to the left Rotate the bits of a component to the left RCL ROL Rotate the bits of a component to the right Multiply an integer by a power of 2 ROR SAL/SHL Divide an integer by a power of 2 Shift the bits of the operand downward SAR SHR Set CF to 1 STC Instruction Set REP Repeat REP Form Prefix Opcode Description Clocks Am186 Am188 REP INS m8,DX F3 6C Input CX bytes from port in DX to ES:[DI] 8+8n 8+8n REP INS m16,DX F3 6D Input CX words from port in DX to ES:[DI] 8+8n 12+8n REP LODS m8 F3 AC Load CX bytes from segment:[SI] in AL 6+11n 6+11n REP LODS m16 F3 AD Load CX words from segment:[SI] in AX 6+11n 10+11n REP MOVS m8,m8 F3 A4 Copy CX bytes from segment:[SI] to ES:[DI] 8+8n 8+8n REP MOVS m16,m16 F3 A5 Copy CX words from segment:[SI] to ES:[DI] 8+8n 12+8n REP OUTS DX,m8 F3 6E Output CX bytes from DS:[SI] to port in DX 8+8n 8+8n REP OUTS DX,m16 F3 6F Output CX words from DS:[SI] to port in DX 8+8n 12+8n REP STOS m8 F3 AA Fill CX bytes at ES:[DI] with AL 6+9n 6+9n REP STOS m16 F3 AB Fill CX words at ES:[DI] with AX 6+9n 10+9n What It Does REP repeatedly executes a single string instruction; an unsigned number in CX tells REP how many times to execute the instruction. Syntax REP instruction Description REP is a prefix that repeatedly executes a single string instruction (INS, LODS, MOVS, OUTS, or STOS). While CX is not 0 and ZF is 1, the microcontroller repeats the following sequence of operations: 1. Acknowledges and services any pending interrupts 2. Executes the string instruction 3. Subtracts 1 from the unsigned number in CX When CX is 0, the microcontroller begins executing the next instruction. Operation It Performs while (CX != 0) /* repeat */ { serviceInterrupts(); execute(instruction); /* decrement counter */ CX = CX - 1; if (ZF == 0) /* not equal */ break; } Instruction Set 4-191 REP REP Flag Settings After Instruction Instruction prefixes do not affect the flags. See the instruction being repeated for the flag values. Examples This example copies one string of ASCII characters stored in memory to another string in the same segment. The microcontroller copies the characters, one by one, from first to last. ; defined in SEG_A segment SOURCE DB ”Source string” DESTINATION DB 13 DUP (?) ; notify assembler: DS and ES specify ; the same segment ASSUME DS:SEG_A, ES:SEG_A ; set up segment registers with same segment MOV AX,SEG_A ; load segment into DS MOV DS,AX ; DS points to SEG_A, source MOV ES,AX ; ES points to SEG_A, destination ; copy one string to another ; set up registers and flags LEA SI,SOURCE ; load source offset (segment = DS) LES DI,DESTINATION ; load dest. offset MOV CX,13 ; set up counter CLD ; process string low to high REP ; copy source string to destination MOVSB Tips To repeat a block of instructions, use LOOP or another looping construct. Related Instructions If you want to See Process string components from lower to higher addresses Copy a component from a port in I/O memory to a string in main memory CLD INS Copy a component from a string in memory to a register Copy a component from one string in memory to another string in memory LODS MOVS Copy a component from a string in main memory to a port in I/O memory Repeat one string comparison instruction while the components are the same OUTS REPE Repeat one string comparison instruction while the components are not the same REPNE Process string components from higher to lower addresses Copy a component from a register to a string in memory 4-192 Instruction Set STD STOS REPE REPZ Repeat While Equal Repeat While Zero REPE Form Prefix Opcode Description Clocks Am186 Am188 REPE CMPS m8,m8 F3 A6 Find nonmatching bytes in ES:[DI] and segment:[SI] 5+22n 5+22n REPE CMPS m16,m16 F3 A7 Find nonmatching words in ES:[DI] and segment:[SI] 5+22n 9+22n REPE SCAS m8 F3 AE Find non-AL byte starting at ES:[DI] 5+15n 5+15n REPE SCAS m16 F3 AF Find non-AX word starting at ES:[DI] 5+15n 9+15n REPZ CMPS m8,m8 F3 A6 Find nonmatching bytes in ES:DI and segment:[SI] 5+22n 5+22n REPZ CMPS m16,m16 F3 A7 Find nonmatching words in ES:DI and segment:[SI] 5+22n 9+22n REPZ SCAS m8 F3 AE Find non-AL byte starting at ES:DI 5+15n 5+15n REPZ SCAS m16 F3 AF Find non-AX word starting at ES:DI 5+15n 9+15n What It Does REPE and REPZ repeatedly execute a single string comparison instruction; an unsigned number in CX tells the microcontroller the maximum number of times to execute the instruction. Once the instruction compares two components and finds they are not equal, the instruction is no longer executed. Syntax REPE instruction REPZ instruction To repeat a string comparison instruction until CX is 0 or two components are not equal, use REPE or its synonym, REPZ. Both forms perform the same operation. Description REPE is a prefix that repeatedly executes a single string comparison instruction (CMPS or SCAS). While CX is not 0 and ZF is 1, the microcontroller repeats the following sequence of operations: 1. Acknowledges and services any pending interrupts 2. Executes the string comparison instruction 3. Subtracts 1 from the unsigned number in CX 4. Compares ZF with 0 When CX is 0 or ZF is 0, the microcontroller begins executing the next instruction. REPZ is a synonym for REPE. Instruction Set 4-193 REPE REPE Operation It Performs while (CX != 0) /* repeat while equal */ { serviceInterrupts(); execute(instruction); /* decrement counter */ CX = CX - 1; if (ZF == 0) /* not equal */ break; } Flag Settings After Instruction Instruction prefixes do not affect the flags. See the instruction being repeated for the flag values. 4-194 Instruction Set REPE REPE Examples This example compares one string of bytes in memory with another string in the same segment until it finds a mismatch or all bytes are compared. The microcontroller copies the bytes, one by one, from first to last. If the strings are different, the following instructions save the segment and offset of the first mismatch. ; defined in SEG_E segment STRING1 DB 20h DUP (?) STRING2 DB LENGTH STRING1 DUP (?) ; notify assembler: DS and ES specify ; the same segment ASSUME DS:SEG_E, ES:SEG_E ; set up segment registers with same segment MOV AX,SEG_E ; load segment into DS MOV DS,AX ; DS points to SEG_E, source MOV ES,AX ; ES points to SEG_E, destination ; compare one string for equality to another ; initialize and use both strings ... ; save ES PUSH ES ; set up registers and flags LEA SI,STRING1 ; LES DI,STRING2 ; MOV CX,LENGTH STRING1 ; CLD ; REPE load source offset (segment = DS) load dest. offset (segment = ES) set up counter process string low to high ; compare first string for equality to second string CMPSB ; if strings are identical, then jump JE EQUAL ; else, DEC LES JMP load segment of mismatch into ES and offset into DI DI ; mismatch is back one byte DI,STRING2[DI] CONTINUE EQUAL: ... CONTINUE: ... ; restore ES POP ES Instruction Set 4-195 REPE REPE Tips To determine the appropriate course of action after a repeated string comparison instruction, use JCXZ to test CX, and use JZ and JNZ to test ZF. To repeat a block of instructions, use LOOPE or another looping construct. Related Instructions If you want to See Process string components from lower to higher addresses Compare a component in one string to a component in another string CLD CMPS Repeat one string instruction REP Repeat one string comparison instruction while the components are not the same REPNE Compare a string component in memory to a register Process string components from higher to lower addresses 4-196 Instruction Set SCAS STD REPNE Repeat While Not Equal REPNZ Repeat While Not Zero REPNE Form Prefix Opcode Description Clocks Am186 Am188 REPNE CMPS m8,m8 F2 A6 Find matching bytes in ES:DI and segment:[SI] 5+22n 5+22n REPNE CMPS m16,m16 F2 A7 Find matching words in ES:DI and segment:[SI] 5+22n 9+22n REPNZ CMPS m8,m8 F2 A6 Find matching bytes in ES:DI and segment:[SI] 5+22n 5+22n REPNZ CMPS m16,m16 F2 A7 Find matching words in ES:DI and segment:[SI] 5+22n 9+22n REPNE SCAS m8 F2 AE Find AL, starting at ES:DI 5+15n 5+15n REPNE SCAS m16 F2 AF Find AX, starting at ES:DI 5+15n 9+15n REPNZ SCAS m8 F2 AE Find AL, starting at ES:DI 5+15n 5+15n REPNZ SCAS m16 F2 AF Find AX, starting at ES:DI 5+15n 9+15n What It Does REPNE and REPNZ repeatedly execute a single string comparison instruction; an unsigned number in CX tells the microcontroller the maximum number of times to execute the instruction. Once the instruction compares two components and finds they are equal, the instruction is no longer executed. Syntax REPNE instruction REPNZ instruction To repeat a string comparison instruction until CX is 0 or two components are equal, use REPNE or its synonym, REPNZ. Both forms perform the same operation. Description REPNE is a prefix that repeatedly executes a single string comparison instruction (CMPS and SCAS). While CX is not 0 and ZF is 0, the microcontroller repeats the following sequence of operations: 1. Acknowledges and services any pending interrupts 2. Executes the string comparison instruction 3. Subtracts 1 from the unsigned number in CX 4. Compares ZF with 1 When CX is 0 or ZF is 1, the microcontroller begins executing the next instruction. REPNZ is a synonym for REPNE. Instruction Set 4-197 REPNE REPNE Operation It Performs while (CX != 0) /* repeat while not equal */ { serviceInterrupts(); execute(instruction); /* decrement counter */ CX = CX - 1; if (ZF == 1) /* equal */ break; } Flag Settings After Instruction Instruction prefixes do not affect the flags. See the instruction being repeated for the flag values. 4-198 Instruction Set REPNE REPNE Examples This example scans a string of 16-bit integers in memory until it finds a particular integer or the entire string is scanned. The microcontroller scans the words, one by one, from first to last. If the string contains the integer, the following instructions save the segment and offset of the integer. ; defined in SEG_S segment STRING DW 16 DUP (?) INTEGER DW -1024 ; FC00h ; notify assembler: DS and ES specify the same segment ASSUME DS:SEG_S, ES:SEG_S ; set up segment registers with same segment MOV AX,SEG_S ; load segment into DS MOV DS,AX ; DS points to SEG_S MOV ES,AX ; ES points to SEG_S ; scan string for integer ; initialize and use string ... ; save ES PUSH ES ; set up registers and flags MOV AX,INTEGER ; LEA DI,STRING ; MOV CX,LENGTH STRING ; CLD ; REPNE AX = INTEGER load offset (segment = DS) set up counter process string low to high ; scan string for integer SCASB ; if the string does not contain -1024, then jump JNE NOT_FOUND ; load segment of integer into ES and offset into DI SUB DI,2 ; integer is back one word LES DI,STRING[DI] JMP FOUND NOT_FOUND: ... FOUND: ... ; restore ES POP ES Instruction Set 4-199 REPNE REPNE Tips To determine the appropriate course of action after a repeated string comparison instruction, use JCXZ to test CX, and use JZ and JNZ to test ZF. To repeat a block of instructions, use LOOPNE or another looping construct. Related Instructions 4-200 If you want to See Process string components from lower to higher addresses Compare a component in one string to a component in another string CLD CMPS Repeat one string instruction Repeat one string comparison instruction while the components are the same REP REPE Compare a string component in memory to a register Process string components from higher to lower addresses SCAS STD Instruction Set REPZ Repeat While Zero REPZ Form Prefix Opcode Description Clocks Am186 Am188 REPZ CMPS m8,m8 F3 A6 Find nonmatching bytes in ES:DI and segment:[SI] 5+22n 5+22n REPZ CMPS m16,m16 F3 A7 Find nonmatching words in ES:DI and segment:[SI] 5+22n 9+22n REPZ SCAS m8 F3 AE Find non-AL byte starting at ES:DI 5+15n 5+15n REPZ SCAS m16 F3 AF Find non-AX word starting at ES:DI 5+15n 9+15n What It Does REPE and REPZ repeatedly execute a single string comparison instruction; an unsigned number in CX tells the microcontroller the maximum number of times to execute the instruction. Once the instruction compares two components and finds they are not equal, the instruction is no longer executed. See REPE on page 4-193 for a complete description. Instruction Set 4-201 RET Return from Procedure RET Clocks Am186 Am188 Form Opcode Description RET C3 Return near to calling procedure 16 20 RET CB Return far to calling procedure 22 30 RET imm16 C2 iw Return near; pop imm16 parameters 18 22 RET imm16 CA iw Return far; pop imm16 parameters 25 33 What It Does Used at the end of a called procedure, RET restores the Instruction Pointer (IP) register and the Code Segment (CS) register (if necessary) and releases any input parameters from the stack before resuming the calling procedure. Syntax RET RET components If the calling procedure doesn’t use the stack to pass input parameters to this procedure, use this form. Also use this form if the calling procedure uses the stack to pass input parameters, and it requires this procedure to pass them back as output parameters. If the calling procedure uses the stack to pass input parameters to this procedure, but it doesn’t need this procedure to pass them back as output parameters, use this form to return and pop the input parameters from the stack. 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 instruction. The optional numeric parameter to the RET instruction gives the number of stack bytes to be released after the return address is popped. These items are typically used as input parameters to the called procedure. For the intrasegment (near) return, the address on the stack is an 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 segment. 4-202 Instruction Set RET RET Operation It Performs /* copy return offset from stack */ IP = SS:[SP]; /* remove storage from stack */ SP = SP + 2; /* If far return */ if opcode==CB or opcode==CA /* copy return segment from stack */ CS = SS:[SP]; if (operands() = 1) { /* remove storage from stack */ SP = SP + 2; SP = SP + components; } Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Instruction Set 4-203 RET RET Examples This example writes a zero-terminated string to the serial port in polled mode. The full address (segment:offset) of the string is passed as an input parameter on the stack. ; initialize and program serial port for transmit ... ; write zero-terminated string to serial port in polled mode ; input parameters: offset of string pushed on stack segment of string pushed on stack SendSerialString PROC MOV PUSHA PUSH BP,SP MOV MOV MOV MOV CLD AX,[BP]+2 DS,AX AX,[BP]+4 SI,AX NEAR ; use BP to access parameters ; save general registers ; save DS DS ; ; ; ; ; get segment of string DS points to string segment get offset of string SI points to string offset process string from low to high SENDSS_LOOP: LODSB CMP AL,0 JZ SENDSS_DONE mSPRT_TXCHAR_P JMP SENDSS_LOOP ; ; ; ; ; load byte from string to AL is character a null? if so, then done transmit character (macro) jump to top of loop SENDSS_DONE: POP POPA RET ; restore saved DS ; restore general registers ; pop string address and return DS 4 SendSerialString ENDP Tips The assembler automatically generates a different machine-language opcode for RET depending on the type of procedure (near or far) in which it is used. Related Instructions If you want to See Call a procedure CALL Reserve storage on the stack for the local variables of a procedure Resume an interrupted procedure ENTER IRET Stop executing the current sequence of instructions and begin another sequence JMP Remove the local variables of a procedure from the stack LEAVE 4-204 Instruction Set ROL* Rotate Left ROL Form Opcode Description Clocks Am186 Am188 ROL r/m8,1 D0 /0 Rotate 8 bits of r/m byte left once 2/15 2/15 ROL r/m8,CL D2 /0 Rotate 8 bits of r/m byte left CL times 5+ n/17+ n 5+ n/17+ n ROL r/m8,imm8 C0 /0 ib Rotate 8 bits of r/m byte left imm8 times 5+ n/17+ n 5+ n/17+ n ROL r/m16,1 D1 /0 Rotate 16 bits of r/m word left once 2/15 2/15 ROL r/m16,CL D3 /0 Rotate 16 bits of r/m word left CL times 5+ n/17+ n 5+ n/17+ n ROL r/m16,imm8 C1 /0 ib Rotate 16 bits of r/m word left imm8 times 5+ n/17+ n 5+ n/17+ n What It Does ROL shifts the bits of a component to the left, overwrites the Carry Flag (CF) with the bit shifted out of the component, and then copies CF to the lowest bit of the component. Syntax ROL component,count Description ROL shifts the bits upward, except for the top bit, which becomes the bottom bit; ROL also copies the bit to CF. The second operand (count) indicates the number of rotations. The operand is either an immediate number or the CL register contents. The microcontroller does not allow rotation counts greater than 31. If count is greater than 31, only the bottom 5 bits of the operand are rotated. Operation It Performs while (i = count; i != 0; i--) /* perform shifts */ { /* store highest bit in carry flag */ CF = mostSignificantBit(component); /* shift left and fill vacancy with bit shifted out */ component = (component << 1) + CF; } if (count == 1) /* single shift */ if (mostSignificantBit(component) != CF) /* set overflow flag */ OF = 1; else /* clear overflow flag */ OF = 0; * – Rotate immediates were not available on the original 8086/8088 systems. Instruction Set 4-205 ROL ROL Flag Settings After Instruction If count=0, flags are unaffected. Otherwise, flags are affected as shown below: OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF ? – – – – – res – res – res 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Undefined unless single-bit rotation, then: OF=1 if result larger than destination operand OF=0 otherwise CF=value of top bit copied into it Tips Use ROL to change the order of the bits within a component. Related Instructions 4-206 If you want to See Rotate the bits of a component and the value of CF to the left Rotate the bits of a component and the value of CF to the right RCL RCR Rotate the bits of a component to the right Multiply an integer by a power of 2 ROR SAL/SHL Divide an integer by a power of 2 Shift the bits of the operand downward SAR SHR Instruction Set ROR* Rotate Right ROR Form Opcode Description Clocks Am186 Am188 ROR r/m8,1 D0 /1 Rotate 8 bits of r/m byte right once 2/15 2/15 ROR r/m8,CL D2 /1 Rotate 8 bits of r/m byte right CL times 5+ n/17+ n 5+ n/17+ n ROR r/m8,imm8 C0 /1 ib Rotate 8 bits of r/m byte right imm8 times 5+ n/17+ n 5+ n/17+ n ROR r/m16,1 D1 /1 Rotate 16 bits of r/m word right once 2/15 2/15 ROR r/m16,CL D3 /1 Rotate 16 bits of r/m word right CL times 5+ n/17+ n 5+ n/17+ n ROR r/m16,imm8 C1 /1 ib Rotate 16 bits of r/m word right imm8 times 5+ n/17+ n 5+ n/17+ n What It Does ROR shifts the bits of a component to the right, overwrites the Carry Flag (CF) with the bit shifted out of the component, and then copies CF to the highest bit of the component. Syntax ROR component,count Description ROR shifts the bits downward, except for the bottom bit, which becomes the top bit. ROR also copies the bit to CF. The second operand (count) indicates the number of rotations to make. The operand is either an immediate number or the CL register contents. The processor does not allow rotation counts greater than 31, using only the bottom five bits of the operand if it is greater than 31. Operation It Performs while (i = count; i != 0; i--) /* perform shifts */ { /* store lowest bit in carry flag */ CF = leastSignificantBit(component); /* shift right and fill vacancy with bit shifted out */ component = (component >> 1) + (CF * pow(2, size(component) - 1)); } if (count == 1) /* single shift */ if (leastSignificantBit(component) != nextMostSignificantBit(component)) /* set overflow flag */ OF = 1; else /* clear overflow flag */ OF = 0; * – Rotate immediates were not available on the original 8086/8088 systems. Instruction Set 4-207 ROR ROR Flag Settings After Instruction If count=0, flags are unaffected. Otherwise, flags are affected as shown below: OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF ? – – – – – res – res – res 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Undefined unless single-bit rotation, then: OF=1 if result larger than destination operand OF=0 otherwise CF=value of top bit copied into it Examples This example determines the number of bits which are set in the AX register. MOV MOV CX,16 BX,0 ; BX contains the number of bits ; which are set in AX LOOP_START: ROR JC LOOP JMP AX,1 INC_COUNT LOOP_START DONE INC_COUNT: INC LOOP BX LOOP_START ; if carry flag is set, increment the count ; increment the count DONE: Tips Use ROR to change the order of the bits within a component. Related Instructions 4-208 If you want to See Rotate the bits of a component and the value of CF to the left Rotate the bits of a component and the value of CF to the right RCL RCR Rotate the bits of a component to the left Multiply an integer by a power of 2 ROL SAL/SHL Divide an integer by a power of 2 Shift the bits of the operand downward SAR SHR Instruction Set 4 SAHF Store AH in Flags SAHF Clocks Am186 Am188 Form Opcode Description SAHF 9E Store AH in low byte of the Processor Status Flags register 3 3 What It Does SAHF copies AH to the low byte of the Processor Status Flags (FLAGS) register. Syntax SAHF Description SAHF loads the SF, ZF, AF, PF, and CF bits in the FLAGS register with values from the AH register, from bits 7, 6, 4, 2, and 0, respectively. Operation It Performs /* copy AH to low byte of FLAGS */ FLAGS = FLAGS | (0x00FF & (AH & 0xD5)); Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF – – – – 11 10 9 8 AF res 7 6 5 PF res 4 3 CF res 2 1 0 ? = undefined; – = unchanged SF=value in bit 7 of AH register CF=value in bit 0 of AH register ZF=value in bit 6 of AH register PF=value in bit 2 of AH register AF=value in bit 4 of AH register Examples This example sets the Carry Flag (CF) to 1. Normally, you use STC to perform this operation. ; set CF to 1 LAHF OR SAHF AH,00000001b ; copy low byte of FLAGS to AH ; set bit 0 (CF) to 1 ; copy AH to low byte of FLAGS Instruction Set 4-209 SAHF SAHF This example prevents an intervening instruction from modifying the Carry Flag (CF), which is used to indicate the status of a hardware device. UMINUEND USUBTRAHEND DW DW 6726 48531 ; 1A46h ; BD93h ; check to see if device is on or off ; return result in CF: 1 = on, 0 = off CALL CHECK_DEVICE ; set up registers MOV CX,UMINUEND MOV BX,USUBTRAHEND ; CX = 1A46h ; BX = BD93h ; save lower five flags in AH LAHF ; unsigned subtraction: CX = CX - BX SUB CX,BX ; CX = 5CB3h, CF = 1 ; restore saved flags from AH SAHF ; CF = outcome of CHECK_DEVICE ; if device is off JNC ALERT_USER ; else JMP ALERT_USER: ... JMP OKAY CONTINUE OKAY: ... CONTINUE: ... Tips SAHF is provided for compatibility with the 8080 microprocessor. It is now customary to use POPF instead. Related Instructions If you want to See Process string components from lower to higher addresses CLD Disable all maskable interrupts Copy the low byte of the Processor Status Flags register to AH CLI LAHF Pop the top component from the stack into the Processor Status Flags register Push the Processor Status Flags register onto the stack POPF PUSHF Process string components from higher to lower addresses STD Enable maskable interrupts that are not masked by their interrupt control registers STI 4-210 Instruction Set SAL* SHL Shift Arithmetic Left Shift Left SAL Form Opcode Description Clocks Am186 Am188 SAL r/m8,1 D0 /4 Multiply r/m byte by 2, once 2/15 2/15 SAL r/m8,CL D2 /4 Multiply r/m byte by 2, CL times 5+ n/17+n 5+ n/17+ n SAL r/m8,imm8 C0 /4 ib Multiply r/m byte by 2, imm8 times 5+ n/17+ n 5+ n/17+ n SAL r/m16,1 D1 /4 Multiply r/m word by 2, once 2/15 2/15 SAL r/m16,CL D3 /4 Multiply r/m word by 2, CL times 5+ n/17+ n 5+ n/17+ n SAL r/m16,imm8 C1 /4 ib Multiply r/m word by 2, imm8 times 5+ n/17+ n 5+ n/17+ n SHL r/m8,1 D0 /4 Multiply r/m byte by 2, once 2/15 2/15 SHL r/m8,CL D2 /4 Multiply r/m byte by 2, CL times 5+ n/17+ n 5+ n/17+ n SHL r/m8,imm8 C0 /4 ib Multiply r/m byte by 2, imm8 times 5+ n/17+ n 5+ n/17+ n SHL r/m16,1 D1 /4 Multiply r/m word by 2, once 2/15 2/15 SHL r/m16,CL D3 /4 Multiply r/m word by 2, CL times 5+ n/17+ n 5+ n/17+ n SHL r/m16,imm8 C1 /4 ib Multiply r/m word by 2, imm8 times 5+ n/17+ n 5+ n/17+ n What It Does SAL and SHL shift the bits of a component to the left, filling vacant bits with 0s. Syntax SAL component,count SHL component,count Description SAL and SHL shift the bits of the operand upward. They shift the high-order bit into CF and clear the low-order bit. The second operand (count) indicates the number of shifts to make. The operand is either an immediate number or the CL register contents. The processor does not allow shift counts greater than 31; it uses only the bottom five bits of the operand if it is greater than 31. * – Shift immediates were not available on the original 8086/8088 systems. Instruction Set 4-211 SAL SAL Operation It Performs while (i = count; i != 0; i--) /* perform shifts */ { /* store highest bit in carry flag */ CF = mostSignificantBit(component); /* shift left and fill vacancy with 0 */ component = component << 1; } if (count == 1) /* single shift */ if (mostSignificantBit(component) != CF) /* set overflow flag */ OF = 1; else /* clear overflow flag */ OF = 0; Flag Settings After Instruction If count=0, flags are unaffected. Otherwise, flags are affected as shown below: OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF ? – – – 11 10 9 8 AF PF res ? res 7 6 5 4 3 CF res 0 2 1 0 ? = undefined; – = unchanged CF=0 unless shift lengths are less than or equal to the size of the shifted operand, then: CF=1 for carry or borrow to high-order bit CF=0 otherwise Undefined unless single-bit shift, then: OF=1 if result larger than destination operand OF=0 otherwise SF=1 if result is 0 or positive SF=0 if result is negative PF=1 if low byte of result has even number of set bits PF=0 otherwise ZF=1 if result equal to 0 ZF=0 if result not equal to 0 Examples This example multiplies a 16-bit integer in memory by 8. POWER2 INTEGER EQU DW 3 -360 ; multiply by 8 ; FE98h ; signed multiplication by 8: INTEGER = INTEGER * pow(2,POWER2) SAL INTEGER,POWER2 ; INTEGER = F4C0h = -2880 This example multiplies an 8-bit unsigned number in AL by 16. POWER2 UNUMBER EQU DB 4 10 ; multiply by 16 ; 0Ah ; unsigned multiplication by 16: AL = AL * pow(2,POWER2) MOV AL,UNUMBER ; AL = 0Ah = 10 SHL AL,POWER2 ; AL = A0h = 160 4-212 Instruction Set SAL SAL This example extracts the middle byte of a word so it can be used by another instruction. SETTINGS DW 1234h ; extract middle byte of AX and place in AH MOV AX,SETTINGS ; AX = 1234h AND AX,0FF0h ; mask middle byte: AX = 0230h SHL AX,4 ; shift middle byte into AH: AX = 2300h Tips Use SHL to isolate part of a component. Use SAL to multiply integers by powers of 2. When multiplying an integer by a power of 2, it is faster to use SAL than IMUL. Related Instructions If you want to See Multiply two integers Multiply two unsigned numbers IMUL MUL Rotate the bits of a component and the value of CF to the left Rotate the bits of a component and the value of CF to the right RCL RCR Rotate the bits of a component to the left Rotate the bits of a component to the right ROL ROR Divide an integer by a power of 2 Shift the bits of the operand downward SAR SHR Instruction Set 4-213 SAR* Shift Arithmetic Right SAR Form Opcode Description Clocks Am186 Am188 SAR r/m8,1 D0 /7 Perform a signed division of r/m byte by 2, once 2/15 2/15 SAR r/m8,CL D2 /7 Perform a signed division of r/m byte by 2, CL times 5+ n/17+ n 5+ n/17+ n SAR r/m8,imm8 C0 /7 ib Perform a signed division of r/m byte by 2, imm8 times 5+ n/17+ n 5+ n/17+ n SAR r/m16,1 D1 /7 Perform a signed division of r/m word by 2, once 2/15 2/15 SAR r/m16,CL D3 /7 Perform a signed division of r/m word by 2, CL times 5+ n/17+ n 5+ n/17+ n SAR r/m16,imm8 C1 /7 ib Perform a signed division of r/m word by 2, imm8 times 5+ n/17+ n 5+ n/17+ n What It Does SAR shifts the bits of a component to the right, filling vacant bits with the highest bit of the original component. Syntax SAR component,count Description SAR shifts the bits of the operand downward and shifts the low-order bit into CF. The effect is to divide the operand by 2. SAR performs a signed divide with rounding toward negative infinity (unlike IDIV); the high-order bit remains the same. The second operand (count) indicates the number of shifts to make. The operand is either an immediate number or the CL register contents. The processor does not allow shift counts greater than 31; it only uses the bottom five bits of the operand if it is greater than 31. Operation It Performs /* store highest bit */ temp = mostSignificantBit(component); while (i = count; i != 0; i--) /* perform shifts */ { /* save lowest bit in carry flag */ CF = leastSignificantBit(component); /* shift right and fill vacancy with sign */ component = cat(temp,(component>>1)); } if (count == 1) /* single shift */ OF = 0; * – Shift immediates were not available on the original 8086/8088 systems. 4-214 Instruction Set SAR SAR Flag Settings After Instruction If count=0, flags are unaffected. Otherwise, flags are affected as shown below: OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF ? – – – 11 10 9 8 AF PF res ? res 7 6 5 4 3 CF res 0 2 1 0 ? = undefined; – = unchanged CF=0 unless shift lengths are less than or equal to the size of the shifted operand, then: CF=1 for carry or borrow to high-order bit CF=0 otherwise Undefined unless single-bit shift, then: OF=1 if result larger than destination operand OF=0 otherwise SF=1 if result is 0 or positive SF=0 if result is negative PF=1 if low byte of result has even number of set bits PF=0 otherwise ZF=1 if result equal to 0 ZF=0 if result not equal to 0 Examples This example divides an 8-bit integer in memory by 2. INTEGER DB -45 ; D3h ; signed division by 2: INTEGER = INTEGER / 2 SAR INTEGER,1 ; INTEGER = EAh = -22 ; remainder in CF This example divides a 16-bit integer in DX by 4. POWER2 INTEGER EQU DW 2 -21 ; divide by 4 ; FFEBh ; signed division by 4: DX = DX / pow(2,POWER2) MOV DX,INTEGER ; DX = FFEBh = -21 SAR DX,POWER2 ; DX = FFFBh = -5 ; remainder is lost Tips If the integer dividend will fit in a 16-bit register and you don’t need the remainder, use SAR to divide integers by powers of 2. When dividing an integer by a power of 2, it is faster to use SAR than IDIV. Related Instructions If you want to See Divide an unsigned number by another unsigned number DIV Divide an integer by another integer Rotate the bits of a component and the value of CF to the left IDIV RCL Rotate the bits of a component and the value of CF to the right Rotate the bits of a component to the left RCR ROL Rotate the bits of a component to the right Multiply an integer by a power of 2 ROR SAL/SHL Divide an unsigned number by a power of 2 SHR Instruction Set 4-215 SBB Subtract Numbers with Borrow SBB Clocks Am186 Am188 Form Opcode Description SBB AL,imm8 1C ib Subtract immediate byte from AL with borrow 3 3 SBB AX,imm16 1D iw Subtract immediate word from AX with borrow 4 4 SBB r/m8,imm8 80 /3 ib Subtract immediate byte from r/m byte with borrow 4/16 4/16 SBB r/m16,imm16 81 /3 iw Subtract immediate word from r/m word with borrow 4/16 4/20 SBB r/m16,imm8 83 /3 ib Subtract sign-extended imm. byte from r/m word with borrow 4/16 4/20 SBB r/m8,r8 18 /r Subtract byte register from r/m byte with borrow 3/10 3/10 SBB r/m16,r16 19 /r Subtract word register from r/m word with borrow 3/10 3/14 SBB r8,r/m8 1A /r Subtract r/m byte from byte register with borrow 3/10 3/10 SBB r16,r/m16 1B /r Subtract r/m word from word register with borrow 3/10 3/14 What It Does SBB subtracts an integer or an unsigned number and the value of the Carry Flag (CF) from another number of the same type. Syntax SBB difference,subtrahend Description SBB adds the second operand (subtrahend) to CF and subtracts the result from the first operand (difference). The result of the subtraction is assigned to the first operand and the flags are set accordingly. Operation It Performs if (size(difference) == 16) if (size(subtrahend) == 8) /* extend sign of subtrahend */ if (subtrahend < 0) subtrahend = 0xFF00 | subtrahend; else subtrahend = 0x00FF & subtrahend; /* subtract with borrow */ difference = difference - subtrahend - CF; 4-216 Instruction Set SBB SBB Flag Settings After Instruction OF DF Processor Status Flags Register – – – 10 9 8 reserved 15 14 13 12 11 IF TF SF ZF AF res 7 6 5 PF res 4 3 CF res 2 1 0 ? = undefined; – = unchanged OF=1 if result larger than destination operand OF=0 otherwise PF=1 if low byte of result has even number of set bits PF=0 otherwise SF=1 if result is 0 or positive SF=0 if result is negative ZF=1 if result equal to 0 ZF=0 if result not equal to 0 CF=1 for carry or borrow to high-order bit CF=0 otherwise AF=1 if carry or borrow to low nibble AF=0 otherwise Examples This example subtracts one 64-bit unsigned number in a register (the subtrahend) from another 64-bit unsigned number in memory (the minuend). UMINUEND USUBTRAHEND WSIZE QSIZE DQ DQ EQU EQU 3B865520F4DE89A1h 0C285DE70893BB2Ah 2 8 ; 64-bit unsigned subtraction: UMINUEND = UMINUEND - USUBTRAHEND ; left (low) word subtraction MOV AX,WORD PTR USUBTRAHEND ; copy subtrahend SUB WORD PTR UMINUEND,AX ; subtract ; set up bases and index MOV SI,WORD PTR UMINUEND MOV DI,WORD PTR USUBTRAHEND MOV BX,WSIZE ; minuend base ; subtrahend base ; set up index ; next higher word subtraction MOV AX,[BX][DI] SBB [BX][SI],AX ; copy subtrahend ; subtract with borrow ; increase index and compare ADD BX,WSIZE CMP BX,QSIZE ; point to next word ; is this the last word? NEXT: ; if not last word, then jump to top of loop JNE NEXT Instruction Set 4-217 SBB SBB This example subtracts one 32-bit integer in a register (the subtrahend) from another 32bit integer in memory (the minuend). This is accomplished by subtracting one word at a time. The first subtraction uses SUB, and the subsequent subtraction uses SBB in case a borrow was generated by the previous subtraction. (CF doubles as the borrow flag. If CF is set, the previous subtraction generated a borrow. Otherwise, the previous subtraction did not generate a borrow.) SMINUEND SSUBTRAHEND DD DD 44761089 -990838848 ; 02AB0001h ; C4F0FFC0h ; 32-bit integer subtraction: SMINUEND = SMINUEND - SSUBTRAHEND ; low word subtraction MOV AX,WORD PTR SSUBTRAHEND SUB WORD PTR SMINUEND,AX ; high word subtraction MOV AX,WORD PTR SSUBTRAHEND + 2 SBB WORD PTR SMINUEND + 2,AX ; copy subtrahend ; subtract ; ; ; ; copy subtrahend subtract with borrow SMINUEND = C79BFFC1h = -946077759 Tips To subtract an integer or an unsigned number located in memory from another number of the same type that is also located in memory, copy one of them to a register before using SBB. SBB requires both operands to be the same size. Before subtracting an 8-bit integer from a 16-bit integer, convert the 8-bit integer to its 16-bit equivalent using CBW. To convert an 8-bit unsigned number to its 16-bit equivalent, use MOV to copy 0 to AH. To subtract numbers larger than 16 bits, use SUB to subtract the low words, and then use SBB to subtract each of the subsequently higher words. The processor does not provide an instruction that performs decimal subtraction. To subtract decimal numbers, use SBB or SUB to perform binary subtraction, and then convert the result to decimal using AAS or DAS. ADC, ADD, SBB, and SUB set AF when the result needs to be converted for decimal arithmetic. AAA, AAS, DAA, and DAS use AF to determine whether an adjustment is needed. This is the only use for AF. Related Instructions 4-218 If you want to See Convert an integer to its 16-bit equivalent Convert an 8-bit unsigned binary difference to its packed decimal equivalent CBW DAS Change the sign of an integer NEG Subtract a number from another number SUB Instruction Set SCAS Scan String for Component SCASB Scan String for Byte SCASW Scan String for Word SCAS Clocks Am186 Am188 Form Opcode Description SCAS m8 AE Compare byte AL to ES:[DI]; update DI 15 19 SCAS m16 AF Compare word AX to ES:[DI]; update DI 15 19 SCASB AE Compare byte AL to ES:[DI]; update DI 15 19 SCASW AF Compare word AX to ES:[DI]; update DI 15 19 What It Does SCAS compares a component in a string to a register. Syntax SCAS destination SCASB SCASW To have the assembler type-check your operand, use this form. The assembler uses the definition of the string component to determine which register to use. To compare AL to a byte within a string located in the segment specified in ES, use this form. Regardless of the form of SCAS you use, destination is always ES:[DI]. Before using any form of SCAS, make sure that ES contains the segment of the string and DI contains the offset of the string. To compare AX to a word within a string located in the segment specified in ES, use this form. Description SCAS subtracts the memory byte or word at the destination index register from the AL or AX register. The result is discarded and only the flags are set. The operand must be addressable from the ES segment. No segment override is possible. The contents of the destination index register determine the address of the memory data being compared, not the SCAS instruction operand. The operand validates ES segment addressability and determines the data type. Load the correct index value into the DI register before executing the SCAS instruction. After the comparison, the destination index register automatically updates. If the Direction Flag (DF) is 0 (see CLD on page 4-231), the destination index register increments. If DF is 1 (see STD on page 4-231), it decrements. The increment or decrement amount is 1 for bytes or 2 for words. The SCASB and SCASW instructions are synonyms for the byte and word SCAS instructions that do not require operands. They are simpler to code, but provide no type or segment checking. Instruction Set 4-219 SCAS SCAS Operation It Performs if (size(destination) == 8) /* compare bytes */ { temp = AL - ES:[DI]; if (DF == 0) /* forward */ increment = 1; else /* backward */ increment = -1; } if (size(destination) == 16) /* compare words */ { temp = AX - ES:[DI]; if (DF == 0) /* forward */ increment = 2; else /* backward */ increment = -2; } /* point to next string component */ DI = DI + increment; Flag Settings After Instruction OF DF Processor Status Flags Register – – – 10 9 8 reserved 15 14 13 12 11 IF TF SF ZF AF res 7 6 5 PF res 4 3 CF res 2 1 0 ? = undefined; – = unchanged OF=1 if result larger than destination operand OF=0 otherwise PF=1 if low byte of result has even number of set bits PF=0 otherwise SF=1 if result is 0 or positive SF=0 if result is negative ZF=1 if result equal to 0 ZF=0 if result not equal to 0 4-220 CF=1 for carry or borrow to high-order bit CF=0 otherwise AF=1 if carry or borrow to low nibble AF=0 otherwise Instruction Set SCAS SCAS Examples This example scans a list of words in memory until it finds a value that is different or all words are compared. The microcontroller scans the words, one by one, from first to last. ; defined in SEG_L LIST DW FILL EQU 32 DUP (?) FFFFh ; notify assembler: DS and ES specify the ; same segment of memory ASSUME DS:SEG_L, ES:SEG_L ; set up segment registers with same segment MOV AX,SEG_L ; load segment into DS and ES MOV DS,AX ; DS points to SEG_L MOV ES,AX ; ES points to SEG_L ; initialize and use list ... ; set up registers and flags MOV AX,FILL ; copy value to AL LEA DI,LIST ; load offset (segment = ES) MOV CX,LENGTH LIST ; set up counter CLD ; process list low to high REPZ ; scan list for different value SCASW ; if list contains different value JNZ ERROR ; else JMP OKAY ERROR: ... JMP CONTINUE OKAY: ... CONTINUE: ... Instruction Set 4-221 SCAS SCAS This example scans a string in memory until it finds a character or the entire string is scanned. The microcontroller scans the bytes, one by one, from first to last. If the string contains the character, the microcontroller sets the Carry Flag (CF) to 1; otherwise, it clears CF to 0. ; defined in SEG_R segment STRING DB 10 DUP (?) AT_SIGN EQU ’@’ ; 40h ; notify assembler: DS and ES specify the ; same segment of memory ASSUME DS:SEG_R, ES:SEG_R ; set up segment registers with same segment MOV AX,SEG_R ; load segment into DS and ES MOV DS,AX ; DS points to SEG_R MOV ES,AX ; ES points to SEG_R ; scan string for character ; initialize and use string ... ; set up registers and flags MOV AL,AT_SIGN ; LEA DI,STRING ; MOV CX,LENGTH STRING ; CLD ; REPNE copy character to AL load offset (segment = ES) set up counter process string low to high ; scan string for character SCASB ; if string contains character JE FOUND ; else JMP NOT_FOUND FOUND: STC JMP NOT_FOUND: CLC ; indicate found CONTINUE ; indicate not found CONTINUE: ... 4-222 Instruction Set SCAS SCAS Tips Before using SCAS, always be sure to: set up DI with the offset of the string, set up CX with the length of the string, and use CLD (forward) or STD (backward) to establish the direction for string processing. To scan a string for a value that is different from a given value, use the REPE (or REPZ) prefix to execute SCAS repeatedly. If all the components match the given value, ZF is set to 1. To scan a string for a value that is the same as a given value, use the REPNE (or REPNZ) prefix to execute SCAS repeatedly. If no components match the given value, ZF is cleared to 0. The string instructions always advance SI and/or DI, regardless of the use of the REP prefix. Be sure to set or clear DF before any string instruction. Related Instructions If you want to See Process string components from lower to higher addresses Compare a component in one string with a component in another string CLD CMPS Repeat one string comparison instruction while the components are the same REPE Repeat one string comparison instruction while the components are not the same REPNE Process string components from higher to lower addresses Instruction Set STD 4-223 SHL* Shift Left SHL Form Opcode Description Clocks Am186 Am188 SHL r/m8,1 D0 /4 Multiply r/m byte by 2, once 2/15 2/15 SHL r/m8,CL D2 /4 Multiply r/m byte by 2, CL times 5+ n/17+ n 5+ n/17+ n SHL r/m8,imm8 C0 /4 ib Multiply r/m byte by 2, imm8 times 5+ n/17+ n 5+ n/17+ n SHL r/m16,1 D1 /4 Multiply r/m word by 2, once 2/15 2/15 SHL r/m16,CL D3 /4 Multiply r/m word by 2, CL times 5+ n/17+ n 5+ n/17+ n SHL r/m16,imm8 C1 /4 ib Multiply r/m word by 2, imm8 times 5+ n/17+ n 5+ n/17+ n What It Does SAL and SHL shift the bits of a component to the left, filling vacant bits with 0s. See SAL on page 4-211 for a complete description. * – Shift immediates were not available on the original 8086/8088 systems. 4-224 Instruction Set SHR* Shift Right SHR Form Opcode Description Clocks Am186 Am188 SHR r/m8,1 D0 /5 Divide unsigned r/m byte by 2, once 2/15 2/15 SHR r/m8,CL D2 /5 Divide unsigned r/m byte by 2, CL times 5+ n/17+ n 5+ n/17+ n SHR r/m8,imm8 C0 /5 ib Divide unsigned r/m byte by 2, imm8 times 5+ n/17+ n 5+ n/17+ n SHR r/m16,1 D1 /5 Divide unsigned r/m word by 2, once 2/15 2/15 SHR r/m16,CL D3 /5 Divide unsigned r/m word by 2, CL times 5+ n/17+ n 5+ n/17+ n SHR r/m16,imm8 C1 /5 ib Divide unsigned r/m word by 2, imm8 times 5+ n/17+ n 5+ n/17+ n What It Does SHR shifts the bits of a component to the right, filling vacant bits with 0s. Syntax SHR component,count Description SHR shifts the bits of the operand downward. SHR shifts the low-order bit into CF. The effect is to divide the operand by 2. SHR performs an unsigned divide and clears the highorder bit. The second operand indicates the number of shifts to make. The operand is either an immediate number or the CL register contents. The processor does not allow shift counts greater than 31; it only uses the bottom 5 bits of the operand if it is greater than 31. Operation It Performs while (i = count; i != 0; i--) /* perform shifts */ { /* save lowest bit in carry flag */ CF = leastSignificantBit(component); /* shift right and fill vacancy with 0 */ component = component >> 1; } if (count == 1) /* single shift */ OF = temp; * – Shift immediates were not available on the original 8086/8088 systems. Instruction Set 4-225 SHR SHR Flag Settings After Instruction If count=0, flags are unaffected. Otherwise, flags are affected as shown below: OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF ? – – – 11 10 9 8 AF PF res ? res 7 6 5 4 3 CF res 0 2 1 0 ? = undefined; – = unchanged CF=0 unless shift lengths are less than or equal to the size of the shifted operand, then: CF=1 for carry or borrow to high-order bit CF=0 otherwise Undefined unless single-bit shift, then: OF=1 if result larger than destination operand OF=0 otherwise SF=1 if result is 0 or positive SF=0 if result is negative PF=1 if low byte of result has even number of set bits PF=0 otherwise ZF=1 if result equal to 0 ZF=0 if result not equal to 0 Examples This example divides an 8-bit unsigned number in memory by 2. POWER2 UNUMBER EQU DB 1 253 ; divide by 2 ; FDh ; unsigned division by 2: UNUMBER = UNUMBER / pow(2,POWER2) SHR UNUMBER,POWER2 ; UNUMBER = 7Dh = 125 ; remainder is lost This example counts the number of bits in a word that are set to 1. LOOP implements a construct equivalent to the C-language do-while loop. AND and JZ implement an if statement within the loop. INDICATORS DW 10110111b ; count number of set bits in word ; set up registers MOV DX,INDICATORS MOV CX,8 * (SIZE INDICATORS) MOV BX,0 4-226 ; B7h ; DX = B7h ; set up counter ; initialize # of set bits TEST_BIT: MOV AND JZ INC AX,DX AX,1h NEXT_BIT BX ; ; ; ; NEXT_BIT: SHR LOOP DX,1 TEST_BIT ; shift next bit into low bit ; decrement CX ; if CX is not 0, jump to top of loop load copy of indicators into AX is low bit set? if not, then jump if so, add 1 to total Instruction Set SHR SHR Tips Use SHR to isolate part of a component. If the dividend will fit in a 16-bit register and you don’t need the remainder, use SHR to divide unsigned numbers by powers of 2. When dividing an unsigned number by a power of 2, it is faster to use SHR than DIV. Related Instructions If you want to See Divide an unsigned number by another unsigned number DIV Divide an integer by another integer Rotate the bits of a component and the value of CF to the left IDIV RCL Rotate the bits of a component and the value of CF to the right Rotate the bits of a component to the left RCR ROL Rotate the bits of a component to the right Multiply an integer by a power of 2 ROR SAL/SHL Divide an integer by a power of 2 SAR Instruction Set 4-227 STC Set Carry Flag STC Clocks Am186 Am188 Form Opcode Description STC F9 Set the Carry Flag to 1 2 2 What It Does STC sets the Carry Flag (CF) to 1. Syntax STC Description STC sets CF. Operation It Performs /* set carry flag */ CF = 1; Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res 1 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Examples This example rotates the bits of a word in memory, maintaining a 1 in the low bit of the word. BITS DW 0100100010001001b ; 4889h ; rotate word, maintaining 1 in low bit STC ; maintain 1 in low bit: CF = 1 RCL BITS,1 ; BITS = 9113h = 1001000100010011b ; CF = 0 4-228 Instruction Set STC STC This example scans a string in memory until it finds a character or the entire string is scanned. The microcontroller scans the bytes, one by one, from first to last. If the string contains the character, the microcontroller sets the Carry Flag (CF) to 1; otherwise, it clears CF to 0. ; defined in SEG_R segment STRING DB 10 DUP (?) AT_SIGN EQU ’@’ ; 40h ; notify assembler: DS and ES specify the ; same segment of memory ASSUME DS:SEG_R, ES:SEG_R ; set up segment registers with same segment MOV AX,SEG_R ; load segment into DS and ES MOV DS,AX ; DS points to SEG_R MOV ES,AX ; ES points to SEG_R ; scan string for character ; initialize and use string ... ; set up registers and flags MOV AL,AT_SIGN ; LEA DI,STRING ; MOV CX,LENGTH STRING ; CLD ; REPNE copy character to AL load offset (segment = ES) set up counter process string low to high ; scan string for character SCASB ; if string contains character JE FOUND ; else JMP NOT_FOUND FOUND: STC JMP NOT_FOUND: CLC ; indicate found CONTINUE ; indicate not found CONTINUE: ... Instruction Set 4-229 STC STC Tips You can use CF to indicate the outcome of a procedure, such as when searching a string for a character. For instance, if the character is found, you can use STC to set CF to 1; if the character is not found, you can use CLC to clear CF to 0. Then, subsequent instructions that do not affect CF can use its value to determine the appropriate course of action. To rotate a 1 into a component, use STC to set CF to 1 before using RCL or RCR. Related Instructions 4-230 If you want to See Clear CF to 0 CLC Toggle the value of CF CMC Instruction Set STD Set Direction Flag STD Clocks Am186 Am188 Form Opcode Description STD FD Set the Direction Flag so the Source Index (SI) and/or the Destination Index (DI) registers will decrement during string instructions 2 2 What It Does STD sets the Direction Flag (DF) to 1, causing subsequent string instructions to process the components of a string from a higher address to a lower address. Syntax STD Description STD sets the Direction Flag, causing all subsequent string operations to decrement the index registers on which they operate, SI or DI or both. Operation It Performs /* process string components from higher to lower addresses */ DF = 1; Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – 1 – – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Instruction Set 4-231 STD STD Examples This example fills a workspace in memory with multiple copies of a string of ASCII characters (a pattern) in the same segment. The characters are copied, one by one, from last to first. ; defined in SEG_T segment WORKSPACE DB 100h DUP (?) ; the following code requires FILLER to be ; reserved immediately following WORKSPACE FILLER DB ”Am186EM-” ; notify assembler: DS and ES specify the ; same segment of memory ASSUME DS:SEG_T, ES:SEG_T ; set up segment registers with same segment MOV AX,SEG_T ; load segment into DS and ES MOV DS,AX ; DS points to SEG_T MOV ES,AX ; ES points to SEG_T ; fill workspace with pattern ; load source offset (segment = DS) LEA SI,FILLER + SIZE FILLER - TYPE FILLER ; load destination offset (segment = ES) LEA DI,FILLER - TYPE FILLER MOV STD REP 4-232 CX,LENGTH WORKSPACE ; set up counter ; process string high to low ; fill destination string with pattern MOVSB Instruction Set STD STD This example copies a string of 16-bit integers in one segment of memory to a string in another segment. The words are copied, one by one, from last to first. ; defined in SEG_A STRING1 DW S1_LENGTH EQU -30000,10250,31450,21540,-16180 5 ; defined in SEG_B STRING2 DW S2_END_ADDR DD S1_LENGTH DUP (?) STRING2 + SIZE STRING2 - TYPE STRING2 ; notify assembler: DS and ES specify ; different segments of memory ASSUME DS:SEG_A, ES:SEG_B ; set up segment registers with different segments MOV AX,SEG_A ; load one segment into DS MOV DS,AX ; DS points to SEG_A MOV AX,SEG_B ; load another segment into ES MOV ES,AX ; ES points to SEG_B ; copy string in segment A to string in segment B ; save ES PUSH ES ; set up registers and flags LEA SI,STRING1 ; load source offset (segment = DS) ; load dest. segment into ES and offset into DI LES DI,ES:S2_END_ADDR MOV CX,S1_LENGTH ; set up counter STD ; process string high to low REP ; copy source string to destination MOVSW ; restore saved ES POP ES Instruction Set 4-233 STD STD Tips Before using one of the string instructions (CMPS, INS, LODS, MOVS, OUTS, SCAS, or STOS), always set up CX with the length of the string, and use CLD (forward) or STD (backward) to establish the direction for string processing. The string instructions always advance SI and/or DI, regardless of the use of the REP prefix. Be sure to set or clear DF before any string instruction. Related Instructions 4-234 If you want to See Process string components from lower to higher addresses CLD Compare a component in one string with a component in another string CMPS Copy a component from a port in I/O memory to a string in main memory Copy a component from a string in memory to a register INS LODS Copy a component from one string in memory to another string in memory Copy a component from a string in main memory to a port in I/O memory MOVS OUTS Compare a component in a string to a register Copy a component from a register to a string in memory SCAS STOS Instruction Set STI Set Interrupt-Enable Flag STI Clocks Am186 Am188 Form Opcode Description STI FB Enable maskable interrupts after the next instruction 2 2 What It Does STI sets the Interrupt-Enable Flag (IF), enabling all maskable interrupts that are not masked by their interrupt control registers. Syntax STI Description STI sets the Interrupt-Enable Flag (IF). The processor responds to external interrupts after executing the next instruction if that instruction does not clear IF. If external interrupts are disabled and the program executes STI before a RET instruction (such as at the end of a subroutine), RET executes before processing any external interrupts. If external interrupts are disabled and the program executes STI before a CLI instruction, no external interrupts are processed because CLI clears IF. STI has no affect on nonmaskable interrupts, or on software-generated interrupts or traps (i.e., INT x). Operation It Performs /* enable maskable interrupts */ IF = 1; Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – 1 – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Instruction Set 4-235 STI STI Examples This example of an interrupt-service routine: enables interrupts so that interrupt nesting can occur, resets a device, disables interrupts until the interrupted procedure is resumed, and then clears the in-service bits in the In-Service (INSERV) register by writing to the EndOf-Interrupt (EOI) register. ; the microcontroller pushes the flags onto ; the stack before executing this routine ; enable interrupt nesting during routine ISR1 PROC FAR PUSHA STI ; save general registers ; enable unmasked maskable interrupts mRESET_DEVICE1 CLI ; perform operation (macro) ; disable maskable interrupts until IRET ; reset MOV MOV OUT in-service bits by writing to EOI register DX,INT_EOI_ADDR ; address of EOI register AX,8000h ; nonspecific EOI DX,AX ; write to EOI register POPA IRET ISR1 ; restore general registers ENDP ; the microcontroller pops the flags from the stack ; before returning to the interrupted procedure Tips Before you use STI, make sure that the stack is initialized (SP and SS). If you disable maskable interrupts using CLI, the microcontroller does not recognize maskable interrupt requests until the instruction that follows STI is executed. After using CLI to disable maskable interrupts, use STI to enable them as soon as possible to reduce the possibility of missing maskable interrupt requests. INT clears IF to 0. IRET restores IF to its value prior to calling the interrupt routine. Related Instructions 4-236 If you want to See Disable all maskable interrupts CLI Instruction Set STOS Store String Component STOSB Store String Byte STOSW Store String Word STOS Clocks Am186 Am188 Form Opcode Description STOS m8 AA Store AL in byte ES:[DI]; update DI 10 10 STOS m16 AB Store AX in word ES:[DI]; update DI 10 14 STOSB AA Store AL in byte ES:[DI]; update DI 10 10 STOSW AB Store AX in word ES:[DI]; update DI 10 14 What It Does STOS copies a component from a register to a string. Syntax STOS destination STOSB STOSW To have the assembler type-check your operand, use this form. The assembler uses the definition of the string component to determine which register to use. To copy AL to a byte within a string located in the segment specified in ES, use this form. Regardless of the form of STOS you use, destination is always ES:[DI]. Before using any form of STOS, make sure that ES contains the segment of the string and DI contains the offset of the string. To copy AX to a word within a string located in the segment specified in ES, use this form. Description STOS transfers the contents of the AL or AX register to the memory byte or word given by the destination register (DI) relative to the ES segment. The destination operand must be addressable from the ES register. A segment override is not possible. The contents of the destination register determine the destination address. STOS does not use an explicit operand. This operand only validates ES segment addressability and determines the data type. You must load the correct index value into the destination register before executing the STOS instruction. After the transfer, STOS automatically updates the Destination Index (DI) register. If the Direction Flag (DF) is 0 (see CLD on page 4-29), the register increments. If DF is 1 (see STD on page 4-231), the register decrements. The increment or decrement amount is 1 for a byte or 2 for a word. STOSB and STOSW are synonyms for the byte and word STOS instructions. These forms do not require an operand and are simpler to use, but provide no type or segment checking. Instruction Set 4-237 STOS STOS Operation It Performs if (size(destination) == 8) /* store bytes */ { ES:[DI] = AL; if (DF == 0) increment = 1; else increment = -1; } /* forward */ /* backward */ if (size(destination) == 16) /* store words */ { ES:[DI] = AX; if (DF == 0) increment = 2; else increment = -2; } /* forward */ /* backward */ /* point to location for next string component */ DI = DI + increment; Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Examples This example fills a string in memory with a character. Because the Direction Flag (DF) is cleared to 0 using CLD, the bytes are filled, one by one, from first to last. STRING ASTERISK DB DB 128 DUP (?) ’*’ ; 2Ah ; fill string with character ; set up registers and flags MOV AL,ASTERISK LEA DI,STRING MOV CX,LENGTH STRING CLD REP 4-238 ; fill string STOSB Instruction Set ; ; ; ; copy character to AL load offset (segment = DS) set up counter process string low to high STOS STOS Tips Before using STOS, always be sure to: set up DI with the offset of the string, set up CX with the length of the string, and use CLD (forward) or STD (backward) to establish the direction for string processing. To fill a string with a given value, use the REP prefix to execute STOS repeatedly. To perform a custom operation on each component in a string, use LODS and STOS within a loop. Within the loop, use the following sequence of instructions: Use LODS to copy a component from memory, use other instructions to perform the custom operation, and then use STOS to copy the component back to memory. To overwrite the original string with the results, set up DI with the same offset as SI before beginning the loop. The string instructions always advance SI and/or DI, regardless of the use of the REP prefix. Be sure to set or clear DF before any string instruction. Related Instructions If you want to See Process string components from lower to higher addresses Copy a component from a port in I/O memory to a string in main memory CLD INS Copy a component from a string in memory to a register Copy a component from one string in memory to another string in memory LODS MOVS Copy a component from a string in main memory to a port in I/O memory Repeat one string instruction OUTS REP Process string components from higher to lower addresses STD Instruction Set 4-239 SUB Subtract Numbers SUB Clocks Am186 Am188 Form Opcode Description SUB AL,imm8 2C ib Subtract immediate byte from AL 3 3 SUB AX,imm16 2D iw Subtract immediate word from AX 4 4 SUB r/m8,imm8 80 /5 ib Subtract immediate byte from r/m byte 4/16 4/16 SUB r/m16,imm16 81 /5 iw Subtract immediate word from r/m word 4/16 4/20 SUB r/m16,imm8 83 /5 ib Subtract sign-extended immediate byte from r/m word 4/16 4/20 SUB r/m8,r8 28 /r Subtract byte register from r/m byte 3/10 3/10 SUB r/m16,r16 29 /r Subtract word register from r/m word 3/10 3/14 SUB r8,r/m8 2A /r Subtract r/m byte from byte register 3/10 3/10 SUB r16,r/m16 2B /r Subtract r/m word from word register 3/10 3/14 What It Does SUB subtracts an integer or an unsigned number from another number of the same type. Syntax SUB difference,subtrahend Description SUB subtracts the second operand (subtrahend) from the first operand (difference). The first operand is assigned the result of the subtraction and the flags are set accordingly. If an immediate byte value is subtracted from a word operand, the immediate value is first sign-extended to the size of the destination operand. Operation It Performs if (size(difference) == 16) if (size(subtrahend) == 8) /* extend sign of subtrahend */ if (subtrahend < 0) subtrahend = 0xFF00 | subtrahend; else subtrahend = 0x00FF & subtrahend; /* subtract */ difference = difference - subtrahend; 4-240 Instruction Set SUB SUB Flag Settings After Instruction OF DF Processor Status Flags Register – – – 10 9 8 reserved 15 14 13 12 11 IF TF SF ZF AF res 7 6 5 PF res 4 3 CF res 2 1 0 ? = undefined; – = unchanged OF=1 if result larger than destination operand OF=0 otherwise CF=1 for carry or borrow to high-order bit CF=0 otherwise PF=1 if low byte of result has even number of set bits PF=0 otherwise SF=1 if result is 0 or positive SF=0 if result is negative AF=1 if carry or borrow to low nibble AF=0 otherwise ZF=1 if result equal to 0 ZF=0 if result not equal to 0 Examples This example subtracts one 16-bit unsigned number in memory (the subtrahend) from another 16-bit unsigned number in a register (the minuend). UMINUEND USUBTRAHEND DW DW 364 25 ; 016Ch ; 0019h ; 16-bit unsigned subtraction: AX = AX - USUBTRAHEND MOV AX,UMINUEND ; AX = 016Ch = 364 SUB AX,USUBTRAHEND ; AX = 0153h = 339 This example subtracts one 32-bit integer in a register (the subtrahend) from another 32bit integer in memory (the minuend). This is accomplished by subtracting one word at a time. The first subtraction uses SUB, and the subsequent subtraction uses SBB in case a borrow was generated by the previous subtraction. (CF doubles as the borrow flag. If CF is set, the previous subtraction generated a borrow. Otherwise, the previous subtraction did not generate a borrow.) SMINUEND SSUBTRAHEND DD DD 44761089 -990838848 ; 02AB0001h ; C4F0FFC0h ; 32-bit integer subtraction: SMINUEND = SMINUEND - SSUBTRAHEND ; low word subtraction MOV AX,WORD PTR SSUBTRAHEND SUB WORD PTR SMINUEND,AX ; high word subtraction MOV AX,WORD PTR SSUBTRAHEND + 2 SBB WORD PTR SMINUEND + 2,AX Instruction Set ; copy subtrahend ; subtract ; ; ; ; copy subtrahend subtract with borrow SMINUEND = C79BFFC1h = -946077759 4-241 SUB SUB Tips To subtract an integer or an unsigned number located in memory from another number of the same type that is also located in memory, copy one of them to a register before using SUB. SUB requires both operands to be the same size. Before subtracting an 8-bit integer from a 16-bit integer, convert the 8-bit integer to its 16-bit equivalent using CBW. To convert an 8-bit unsigned number to its 16-bit equivalent, use MOV to copy 0 to AH. To subtract numbers larger than 16 bits, use SUB to subtract the low words, and then use SBB to subtract each of the subsequently higher words. Use DEC instead of SUB within a loop when you want to decrease a value by 1 each time the loop is executed. The processor does not provide an instruction that performs decimal subtraction. To subtract decimal numbers, use SBB or SUB to perform binary subtraction, and then convert the result to decimal using AAS or DAS. ADC, ADD, SBB, and SUB set AF when the result needs to be converted for decimal arithmetic. AAA, AAS, DAA, and DAS use AF to determine whether an adjustment is needed. This is the only use for AF. Related Instructions 4-242 If you want to See Convert an 8-bit unsigned binary difference to its unpacked decimal equivalent Convert an integer to its 16-bit equivalent AAS CBW Compare two components using subtraction and set the flags accordingly Convert an 8-bit unsigned binary difference to its packed decimal equivalent CMP DAS Decrement an integer or unsigned number by 1 DEC Change the sign of an integer Subtract a number and the value of CF from another number NEG SBB Instruction Set TEST Logical Compare TEST Clocks Am186 Am188 Form Opcode Description TEST AL,imm8 A8 ib AND immediate byte with AL 3 3 TEST AX,imm16 A9 iw AND immediate word with AX 4 4 TEST r/m8,imm8 F6 /0 ib AND immediate byte with r/m byte 4/10 4/10 TEST r/m16,imm16 F7 /0 iw AND immediate word with r/m word 4/10 4/14 TEST r/m8,r8 84 /r AND byte register with r/m byte 3/10 3/10 TEST r/m16,r16 85 /r AND word register with r/m word 3/10 3/14 What It Does TEST determines whether particular bits of a component are set to 1 by comparing the component to a mask. Syntax TEST component,mask Description TEST computes the bitwise 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. Operation It Performs /* compare component to mask */ temp = component & mask; /* clear overflow and carry flags */ OF = CF = 0; Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF 0 – – – 11 10 9 8 AF PF res ? res 7 6 5 4 3 CF res 0 2 1 0 ? = undefined; – = unchanged SF=1 if result is 0 or positive SF=0 if result is negative ZF=1 if result equal to 0 ZF=0 if result not equal to 0 PF=1 if low byte of result has even number of set bits PF=0 otherwise Instruction Set 4-243 TEST TEST Examples This example tests the value of a bit that a particular device sets to 1 when an error occurs. If the tested bit is 1, the microcontroller jumps to an instruction sequence designed to reset the device. Otherwise, the microcontroller continues with the following instruction. DEVICE5 DEVICES EQU DB 00100000b ? ; device 5 mask ; test for device error ; update device status bits ... TEST JNZ ... DEVICES,DEVICE5 RESET5 ; did device 5 log an error? ; if so, try to reset device 5 RESET5: ... Tips If you want a procedure to branch depending on the value of one or more bits, use TEST to test those bits and affect ZF, and then use JZ or JNZ. Related Instructions 4-244 If you want to See Clear particular bits of a component to 0 Compare two values using subtraction and set the flags accordingly AND CMP Instruction Set WAIT* Wait for Coprocessor WAIT Clocks Am186 Am188 Form Opcode Description WAIT 9B Performs a NOP. N/A N/A What It Does WAIT is unimplemented and performs a NOP. Syntax WAIT Description Members of the Am186 and Am188 family of microcontrollers do not have a TEST pin, and executing WAIT is the same as performing a NOP. Operation It Performs NOP ; does nothing Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged * – This instruction is not supported with the necessary pinout. Instruction Set 4-245 XCHG Exchange Components XCHG Clocks Am186 Am188 Form Opcode Description XCHG AX,r16 90+ rw Exchange word register with AX 3 3 XCHG r16,AX 90+ rw Exchange AX with word register 3 3 XCHG r/m8,r8 86 /r Exchange byte register with r/m byte 4/17 4/17 XCHG r8,r/m8 86 /r Exchange r/m byte with byte register 4/17 4/17 XCHG r/m16,r16 87 /r Exchange word register with r/m word 4/17 4/21 XCHG r16,r/m16 87 /r Exchange r/m word with word register 4/17 4/21 What It Does XCHG exchanges one component with another component. Syntax XCHG component1,component2 Description XCHG exchanges two operands. The operands can be in either order. Operation It Performs /* save first component */ temp = component1; /* copy second component to first component */ component1 = component2; /* copy saved component to second component */ component2 = temp; Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF AF PF CF – – – – – – res – res – res – 11 10 9 8 7 6 5 4 3 2 1 0 ? = undefined; – = unchanged Examples This example exchanges an integer in one register with an integer in another register. ; exchange BX with CX MOV BX,-300 MOV CX,700 XCHG BX,CX 4-246 ; BX = -300 ; CX = 700 ; BX = 700, CX = -300 Instruction Set XCHG XCHG This example performs a bubble sort on a list of unsigned numbers in memory. The microcontroller rearranges the list from smallest to largest. LIST L_LENGTH DB EQU 3,5,2,9,7 5 ; sort unsigned numbers MOV MOV MOV SI,0 DX,L_LENGTH - 1 CX,DX ; set up list index ; get length of list ; set up counter MOV CMP JLE AL,LIST[SI] AL,LIST[SI]+1 NEXT ; copy this number ; is this number <= next number? ; if so, then jump XCHG MOV AL,LIST[SI]+1 LIST[SI],AL ; write larger number to next byte ; write smaller number to this byte INC LOOP SI SORT ; point to next number ; while CX is not zero, jump ; to top of loop DEC MOV MOV LOOP DX SI,0 CX,DX SORT ; ; ; ; ; SORT: NEXT: set up length of sublist reset sublist index set up sublist counter while CX is not zero, jump to top of loop Tips To exchange two components that are both stored in memory, use MOV to copy the first component to a register, use XCHG to exchange the register with the second component, and then use MOV again to copy the register to the first component. XCHG requires both operands to be the same size. To convert an 8-bit integer to its 16bit equivalent, use CBW. To convert a 16-bit integer to its 32-bit equivalent, use CWD. To convert another type of component to its extended equivalent, use MOV to copy 0 to the high byte or word. You cannot use XCHG to exchange a word with a segment register. To copy a segment address to a segment register, use MOV to copy the segment address to a general register, and then use MOV to copy the value in the general register to the segment register. Related Instructions If you want to See Copy a component to a register or a location in memory MOV Instruction Set 4-247 XLAT Translate Table Index to Component XLATB Translate Table Index to Byte XLAT Clocks Am186 Am188 Form Opcode Description XLAT m8 D7 Set AL to memory byte segment:[BX+unsigned AL] 11 15 XLATB D7 Set AL to memory byte DS:[BX+unsigned AL] 11 15 What It Does XLAT translates the offset index of a byte stored in memory to the value of that byte. Syntax XLAT base XLATB Use this form to override the default source segment (DS), and to have the assembler type-check your operand. In this form, base is segment:[BX]. To translate AL to the value of the byte located at offset [BX][AL] in the segment specified in DS, use this form. Description XLAT changes the AL register from the table index to the table entry. The AL register should be an unsigned index into a table addressed by the DS:BX register pair. The operand allows for the possibility of a segment override, but the instruction uses the contents of the BX register even if it differs from the offset of the operand. Load the operand offset into the BX register—and the table index into AL—before executing XLAT. Use the no-operand form, XLATB, if the table referenced by BX resides in the DS segment. Operation It Performs /* extend index */ temp = 0x00FF & AL; /* store indexed component in AL */ AL = DS:[BX + temp]; Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF PF CF – – – – – res – res – res – 11 10 9 8 7 6 ? = undefined; – = unchanged 4-248 AF – Instruction Set 5 4 3 2 1 0 XLAT XLAT Examples This example translates a string of ASCII numbers in memory to unpacked decimal digits. The microcontroller translates the numbers, one by one, from first to last. ; defined in SEG_D segment TABLE DB 0,1,2,3,4,5,6,7,8,9 STRING DB ”0123456789” ; notify assembler: DS and ES specify the ; same segment of memory ASSUME DS:SEG_D, ES:SEG_D ; set up DS and ES with the same segment address MOV AX,SEG_D ; load segment into DS and ES MOV DS,AX ; DS points to SEG_D MOV ES,AX ; ES points to SEG_D ; translate ASCII numbers to unpacked decimal digits ; set up for string operation LEA SI,STRING ; load source offset (segment = DS) LEA DI,STRING ; load dest. offset (segment = DS) MOV CX,10 ; set up counter CLD ; process string from low to high LEA BX,TABLE ; load table base (segment = DS) ASCII2BCD: ; translate bytes LODSB XLATB STOSB LOOP ASCII2BCD ; ; ; ; ; copy ASCII # from string to AL translate to unpacked decimal copy back to string while CX is not 0, jump to top of loop This example translates the offset (base+index) of a byte within a table in memory to the value of that byte. ; defined in SEG_B segment TABLE DB 3,6,12,24,48,96,192 ; notify assembler: DS and ES point to ; different segments of memory ASSUME DS:SEG_A, ES:SEG_B ; set up DS and ES with different segment addresses MOV AX,SEG_A ; load one segment into DS MOV DS,AX ; DS points to SEG_A MOV AX,SEG_B ; load another segment into ES MOV ES,AX ; ES points to SEG_B ; translate index to component (override default segment) MOV AL,3 ; set up index: AL = 3 LEA BX,ES:TABLE ; load table base into BX XLAT ES:[BX] ; translate: AL = 24 Instruction Set 4-249 XLAT XLAT Tips Use XLAT to translate bytes from one code system to another (e.g., from unpacked decimal numbers to ASCII numbers or from ASCII characters to EBCDIC characters). Related Instructions 4-250 If you want to See Load the offset of a table in memory into BX LEA Instruction Set XOR Logical Exclusive OR XOR Clocks Am186 Am188 Form Opcode Description XOR AL,imm8 34 ib XOR immediate byte with AL 3 3 XOR AX,imm16 35 iw XOR immediate word with AX 4 4 XOR r/m8,imm8 80 /6 ib XOR immediate byte with r/m byte 4/16 4/16 XOR r/m16,imm16 81 /6 iw XOR immediate word with r/m word 4/16 4/20 XOR r/m16,imm8 83 /6 ib XOR sign-extended immediate byte with r/m word 4/16 4/20 XOR r/m8,r8 30 /r XOR byte register with r/m byte 3/10 3/10 XOR r/m16,r16 31 /r XOR word register with r/m word 3/10 3/14 XOR r8,r/m8 32 /r XOR r/m byte with byte register 3/10 3/10 XOR r16,r/m16 33 /r XOR r/m word with word register 3/10 3/14 What It Does XOR complements particular bits of a component according to a mask. Syntax XOR component,mask Description XOR computes the exclusive OR of the two operands. If corresponding bits of the operands are different, the resulting bit is 1. If the bits are the same, the result is 0. The answer replaces the first operand. Operation It Performs /* XOR component with mask */ component = component ^ mask; /* clear overflow and carry flags */ OF = CF = 0; Flag Settings After Instruction OF DF Processor Status Flags Register reserved 15 14 13 12 IF TF SF ZF 0 – – – 11 10 9 8 AF PF res ? res 7 6 5 4 3 CF res 0 2 1 0 ? = undefined; – = unchanged SF=1 if result is 0 or positive SF=0 if result is negative ZF=1 if result equal to 0 ZF=0 if result not equal to 0 PF=1 if low byte of result has even number of set bits PF=0 otherwise Instruction Set 4-251 XOR XOR Examples This example turns on Timer 2 by setting the Enable (EN) and Inhibit (INH) bits in the Timer 2 Mode and Control (T2CON) register. TMR2_CNT_ON EQU 0C000h ; turn on Timer MOV IN XOR OUT 2 DX,TMR2_CTL_ADDR AX,DX AX,TMR2_CTL_ON DX,AX ; mask for enable & inhibit bits ; ; ; ; address of T2CON register read T2CON into AX set enable & inhibit bits write AX to T2CON This example procedure turns an LED on or off by toggling the signal level of programmable I/O (PIO) pin 3 in the PIO Data 0 (PDATA0) register. PIO3_MASK EQU ; toggle PDATA0 bit 3 TOGGLE_PIO3 PROC 0008h ; PDATA0 bit 3 NEAR ; save registers PUSH AX PUSH DX MOV IN XOR OUT DX,PIO_DATA0_ADDR AX,DX AX,PIO3_MASK DX,AX ; ; ; ; address of PDATA0 register read PDATA0 into AX toggle bit 3 write AX to PDATA0 ; restore saved registers POP DX POP AX RET TOGGLE_PIO3 ENDP Tips To clear a register to 0, use XOR to exclusive OR the register with itself. Related Instructions 4-252 If you want to See Clear particular bits of a component to 0 AND Toggle all bits of a component Set particular bits of a component to 1 NOT OR Instruction Set APPENDIX A INSTRUCTION SET SUMMARY This appendix provides several tables that summarize the instructions for the Am186 and Am188 family of microcontrollers: n Table A-2, “Instruction Set Summary by Mnemonic,” on page A-3 n Table A-3, “Instruction Set Summary by Opcode,” on page A-10 n Table A-4, “Instruction Set Summary by Partial Opcode,” on page A-20 The variables used in these tables are described in Table A-1 on page A-2. Table A-4 also uses the variables in Table A-5 on page A-22. The format for the instructions is described in "Forms of the Instruction" on page 2-4. Instruction Set Summary A-1 Table A-1 Variables Used In Instruction Set Summary Tables Variable Function Values Description d 0 to r/m 1 to reg Specifies direction. data-8 data-low data-high data-SX Specifies a non-address constant data used by the instruction. The "8" indicates an 8-bit constant; "low", the low-order byte of a 16-bit constant; "high", the high order byte of a 16-bit constant; and "SX", an 8bit constant that is sign-extended for a 16-bit operation. disp-8 disp-low disp-high Specifies the displacement. The "8" indicates an 8bit displacement; "low", the low-order byte of a 16-bit displacement; and "high", the high-order byte of a 16bit displacement. For some forms of MOV, specifies a 0-relative address. mod Along with r/m, determines the effective address of 11 the memory operand. 00 1 r/m is treated as a reg field DISP = 0, disp-low and disp-high are absent DISP = disp-low sign-extended to 16-bits, disp-high is absent DISP = disp-high: disp-low EA = (BX)+(SI)+DISP EA = (BX)+(DI)+DISP EA = (BP)+(SI)+DISP EA = (BP)+(DI)+DISP EA = (SI)+DISP EA = (DI)+DISP EA = (BP)+DISP (except if mod=00, then EA = disp-high:disp:low) EA = (BX)+DISP AL, if w=0 or implicit 8-bit AX, if w=1 or implicit 16-bit CL, if w=0 or implicit 8-bit CX, if w=1 or implicit 16-bit DL, if w=0 or implicit 8-bit DX, if w=1 or implicit 16-bit BL, if w=0 or implicit 8-bit BX, if w=1 or implicit 16-bit AH, if w=0 or implicit 8-bit SP, if w=1 or implicit 16-bit CH, if w=0 or implicit 8-bit BP, if w=1 or implicit 16-bit DH, if w=0 or implicit 8-bit SI, if w=1 or implicit 16-bit BH, if w=0 or implicit 8-bit DI, if w=1 or implicit 16-bit no sign extension sign-extend (for 16-bit operations only, w=1) 00 ES register 01 CS register 10 SS register 11 DS register 0 8-bit value 1 16-bit value 01 10 r/m Along with mod, determines the effective address of 000 the memory operand. 001 010 011 100 101 110 111 reg Represents a register, and is assigned according to 000 the value of w and reg. 001 010 011 100 101 110 111 s Specifies immediate operand sign-extension. seg-low seg-high Specifies the segment base address value. Represents the high-order 16 bits of a 20-bit address, with an implicit 4 low-order 0 bits. sreg Specifies a segment register. w XXX YYY Specifies an 8- or 16-bit value. 0 Specifies opcode to proc. ext. Notes: 1 – DISP follows the operand address (before data if required). 2 – The physical addresses of all operands addressed by the BP register are computed using the SS segment register. The physical addresses of the destination operands of the string primitive operations (those addressed by the DI register) are computed using the ES segment, which cannot be overridden. A-2 Instruction Set Summary Table A-2 Instruction Set Summary by Mnemonic For More Info., See Page Instruction Opcode AAA = ASCII adjust AL after add 0011 0111 AAD = ASCII adjust AX before divide 1101 0101 0000 1010 4-4 AAM = ASCII adjust AL after multiply 1101 0100 0000 1010 4-6 AAS = ASCII adjust AL after subtract 0011 1111 4-2 4-8 ADC = Add numbers with carry: 4-10 Reg/memory and register to either 0001 00dw mod reg r/m Immediate to register/memory 1000 00sw mod 010 r/m data-8/data-low data-8/data-low data-high if w=1 data-high if sw=01 (sw≠10) Immediate to accumulator 0001 010w ADD = Add numbers: 4-14 Reg/mem and register to either 0000 00dw mod reg r/m Immediate to register/memory 1000 00sw mod 000 r/m data-8/data-low data-8/data-low data-high if w=1 data-high if sw=01 (sw≠10) Immediate to accumulator 0000 010w AND = Logical AND: 4-17 Reg/memory and register to either 0010 00dw mod reg r/m Immediate to register/memory 1000 00sw mod 100 r/m data-8/data-low data-high if w=1 data-high if sw=01 (sw≠10) Immediate to accumulator 0010 010w data-8/data-low BOUND = Check array index against bounds* 0110 0010 mod reg r/m 4-19 CALL = Call procedure: 4-21 Direct within segment 1110 1000 disp-low disp-high Register mem. indirect within seg. 1111 1111 mod 010 r/m Direct intersegment 1001 1010 disp-low disp-high seg-low seg-high mod 011 r/m (mod ≠ 11) Indirect intersegment 1111 1111 CBW = Convert byte integer to word 1001 1000 4-24 CLC = Clear carry flag 1111 1000 4-26 CLD = Clear direction flag 1111 1100 4-29 CLI = Clear interrupt-enable flag 1111 1010 4-31 CMC = Complement carry flag 1111 0101 4-33 Notes: * Indicates instructions not available in 8086 or 8088 systems. **Indicates instructions that are not supported with the necessary pinout. ***The external LOCK pin is only available on some members of the Am186 and Am188 family of microcontrollers. However, LOCK internal logic is still in effect on parts without the LOCK pin. Instruction Set Summary A-3 Table A-2 Instruction Set Summary by Mnemonic Instruction For More Info., See Page Opcode CMP = Compare: 4-34 Reg/memory and register to either 0011 10dw mod reg r/m Immediate with register/memory 1000 00sw mod 111 r/m data-8/data-low data-8/data-low data-high if w=1 data-high if sw=01 (sw≠10) Immediate with accumulator 0011 110w CMPS/CMPSB/CMPSW = Compare string 1010 011w 4-36 CS = CS segment register override prefix 0010 1110 2-2 CWD = Convert word integer to doubleword 1001 1001 4-40 DAA = Decimal adjust AL after add 0010 0111 4-42 DAS = Decimal adjust AL after subtract 0010 1111 4-45 DEC = Decrement by 1: 4-48 Register/memory 1111 111w mod 001 r/m Register 0 1 0 0 1 reg DIV = Divide unsigned numbers 1111 011w DS = DS segment register override prefix 0011 1110 ENTER = Enter high-level procedure* 1100 1000 ES = ES segment register override prefix 0010 0110 ESC = Processor extension escape** 1101 1XXX HLT = Halt 1111 0100 IDIV = Integer divide (signed) 1111 011w mod 111 r/m 4-60 IMUL = Integer multiply (signed) 1111 011w mod 101 r/m 4-63 IMUL = Integer immediate multiply (signed)* 0110 10s1 mod reg r/m mod 110 r/m 4-50 2-2 data-low data-high data-8 4-53 2-2 mod YYY r/m (XXX YYY are opcode to proc. ext.) 4-56 4-57 IN = Input from: data-8/data-low data-high if s=0 4-63 4-67 Fixed port 1110 010w Variable port 1110 110w data-8 INC = Increment by 1: 4-69 Register/memory 1111 111w Register 0 1 0 0 0 reg INS/INSB/INSW = Input string from DX port* 0110 110w mod 000 r/m 4-71 INT = Interrupt: 4-73 Type specified 1100 1101 Type 3 1100 1100 data-8 Notes: * Indicates instructions not available in 8086 or 8088 systems. **Indicates instructions that are not supported with the necessary pinout. ***The external LOCK pin is only available on some members of the Am186 and Am188 family of microcontrollers. However, LOCK internal logic is still in effect on parts without the LOCK pin. A-4 Instruction Set Summary Table A-2 Instruction Set Summary by Mnemonic Instruction Opcode For More Info., See Page INTO = Interrupt on overflow 1100 1110 4-73 IRET = Interrupt return 1100 1111 4-76 JA/JNBE = Jump on: above/not below or equal 0111 0111 disp-8 4-78 JAE/JNB/JNC = Jump on: above or equal/not below/not carry 0111 0011 disp-8 4-80 JB/JC/JNAE = Jump on: below/ compare/not above or equal 0111 0010 disp-8 4-82 JBE/JNA = Jump on: below or equal/not above 0111 0110 disp-8 4-84 JCXZ = Jump on CX = zero 1110 0011 disp-8 4-87 JE/JZ = Jump on: equal/zero 0111 0100 disp-8 4-89 JG/JNLE = Jump on: greater/not less or equal 0111 1111 disp-8 4-91 JGE/JNL = Jump on: greater or equal/ not less 0111 1101 disp-8 4-93 JL/JNGE = Jump on: less/not greater or equal 0111 1100 disp-8 4-95 JLE/JNG = Jump on: less or equal/not greater 0111 1110 disp-8 4-97 JMP = Unconditional jump: 4-99 Short/long 1110 1011 disp-8 Direct within segment 1110 1001 disp-low Register/mem indirect within seg. 1111 1111 mod 100 r/m Direct intersegment 1110 1010 disp-low disp-high seg-low seg-high (mod ≠ 11) disp-high Indirect intersegment 1111 1111 mod 101 r/m JNE/JNZ = Jump on: not equal/not zero 0111 0101 disp-8 4-107 JNO = Jump on not overflow 0111 0001 disp-8 4-113 JNS = Jump on not sign 0111 1001 disp-8 4-116 JO = Jump on overflow 0111 0000 disp-8 4-119 JPE/JP = Jump on: parity even/parity 0111 1010 disp-8 4-122 JPO/JNP = Jump on: parity odd/not parity 0111 1011 disp-8 4-124 JS = Jump on sign 0111 1000 disp-8 4-126 LAHF = Load AH with flags 1001 1111 LDS = Load pointer to DS 1100 0101 mod reg r/m LEA = Load EA to register 1000 1101 mod reg r/m 4-129 (mod≠11) 4-131 4-133 Notes: * Indicates instructions not available in 8086 or 8088 systems. **Indicates instructions that are not supported with the necessary pinout. ***The external LOCK pin is only available on some members of the Am186 and Am188 family of microcontrollers. However, LOCK internal logic is still in effect on parts without the LOCK pin. Instruction Set Summary A-5 Table A-2 Instruction Set Summary by Mnemonic Instruction Opcode For More Info., See Page LEAVE = Leave procedure* 1100 1001 4-135 LES = Load pointer to ES 1100 0100 LOCK = Bus lock prefix*** 1111 0000 4-140 LODS/LODSB/LODSW = Load string to AL/AX 1010 110w 4-141 LOOP = Loop CX Times 1110 0010 disp-8 4-146 LOOPE/LOOPZ = Loop while: equal/ zero 1110 0001 disp-8 4-148 LOOPNE/LOOPNZ = Loop while: not equal/not zero 1110 0000 disp-8 4-150 mod reg r/m (mod ≠ 11) 4-138 MOV = Move: 4-153 Register to register/memory 1000 100w mod reg r/m Register/memory to register 1000 101w mod reg r/m Immediate to register/memory 1100 011w mod 000 r/m data-8/data-low Immediate to register 1 0 1 1 w reg data-8/data-low data-high if w=1 Memory to accumulator 1010 000w disp-low disp-high Accumulator to memory 1010 001w disp-low disp-high Register/mem. to segment register 1000 1110 mod 0 sreg r/m Segment reg. to register/memory 1000 1100 mod 0 sreg r/m MOVS/MOVSB/MOVSW = Move string to byte/word 1010 010w MUL = Multiply (unsigned) 1111 011w mod 100 r/m 4-160 NEG = Change sign reg./memory 1111 011w mod 011 r/m 4-163 NOP = No Operation 1001 0000 NOT = Invert register/memory 1111 011w data-high if w=1 4-156 4-165 mod 010 r/m 4-167 OR = Or: 4-169 Reg/memory and register to either 0000 10dw mod reg r/m Immediate to register/memory 1000 00sw mod 001 r/m data-8/data-low data-8/data-low data-high if w=1 data-high if sw=01 (sw≠10) Immediate to accumulator 0000 110w OUT = Output to: 4-171 Fixed port 1110 011w Variable port 1110 111w OUTS/OUTSB/OUTSW = Output string to DX port* 0110 111w data-8 4-173 Notes: * Indicates instructions not available in 8086 or 8088 systems. **Indicates instructions that are not supported with the necessary pinout. ***The external LOCK pin is only available on some members of the Am186 and Am188 family of microcontrollers. However, LOCK internal logic is still in effect on parts without the LOCK pin. A-6 Instruction Set Summary Table A-2 Instruction Set Summary by Mnemonic Instruction For More Info., See Page Opcode POP = Pop: 4-175 Memory 1000 1111 mod 000 r/m Register 0 1 0 1 1 reg Segment register 0 0 0 sreg 1 1 1 POPA = Pop All* 0110 0001 4-178 POPF = Pop flags 1001 1101 4-180 (sreg ≠01) PUSH = Push: 4-181 Memory 1111 1111 mod 110 r/m Register 0 1 0 1 0 reg Segment register 0 0 0 sreg 1 1 0 Immediate* 0110 10s0 PUSHA = Push All* 0110 0000 4-184 PUSHF = Push flags 1001 1100 4-186 data-8/data-low data-high if s=0 RCL = Rotate through carry left 4-187 Register/Memory by 1 1101 000w mod 010 r/m Register/Memory by CL 1101 001w mod 010 r/m Register/Memory by Count* 1100 000w mod 010 r/m data-8 RCR = Rotate through carry right 4-189 Register/Memory by 1 1101 000w mod 011 r/m Register/Memory by CL 1101 001w mod 011 r/m Register/Memory by Count* 1100 000w mod 011 r/m REP (repeat by count in CX) data-8 4-191 INS = Input string from DX port* 1111 0011 0110 110w LODS = Load string 1111 0011 1010 110w MOVS = Move string 1111 0011 1010 010w OUTS = Output string* 1111 0011 0110 111w STOS = Store string 1111 0011 1010 101w REPE/REPZ (repeat by count in CX while equal/while zero) CMPS = Compare string 1111 0011 1010 011w SCAS = Scan string 1111 0011 1010 111w REPNE/REPNZ (repeat by count in CX while not equal/while not zero) CMPS = Compare string 1111 0010 1010 011w SCAS = Scan string 1111 0010 1010 111w 4-193 4-197 Notes: * Indicates instructions not available in 8086 or 8088 systems. **Indicates instructions that are not supported with the necessary pinout. ***The external LOCK pin is only available on some members of the Am186 and Am188 family of microcontrollers. However, LOCK internal logic is still in effect on parts without the LOCK pin. Instruction Set Summary A-7 Table A-2 Instruction Set Summary by Mnemonic Instruction For More Info., See Page Opcode RET = Return from CALL: 4-202 Within segment 1100 0011 Within seg adding immed. to SP 1100 0010 Intersegment 1100 1011 Intersegment adding immed. to SP 1100 1010 data-low data-high data-low data-high ROL = Rotate left 4-205 Register/Memory by 1 1101 000w mod 000 r/m Register/Memory by CL 1101 001w mod 000 r/m Register/Memory by Count* 1100 000w mod 000 r/m data-8 ROR = Rotate right 4-207 Register/Memory by 1 1101 000w mod 001 r/m Register/Memory by CL 1101 001w mod 001 r/m Register/Memory by Count* 1100 000w mod 001 r/m SAHF = Store AH in flags 1001 1110 data-8 4-209 SAL/SHL = Shift arithmetic left/shift left 4-211 Register/Memory by 1 1101 000w mod 100 r/m Register/Memory by CL 1101 001w mod 100 r/m Register/Memory by Count* 1100 000w mod 100 r/m data-8 SAR = Shift arithmetic right 4-214 Register/Memory by 1 1101 000w mod 111 r/m Register/Memory by CL 1101 001w mod 111 r/m Register/Memory by Count* 1100 000w mod 111 r/m data-8 SBB = Subtract with borrow: 4-216 Reg/memory and register to either 0001 10dw mod reg r/m Immediate from register/memory 1000 00sw mod 011 r/m data-8/data-low data-8/data-low data-high if w=1 data-high if sw=01 (sw≠10) Immediate from accumulator 0001 110w SCAS/SCASB/SCASW = Scan string for byte/word 1010 111w 4-219 SHR = Shift right 4-225 Register/Memory by 1 1101 000w mod 101r/m Register/Memory by CL 1101 001w mod 101 r/m Register/Memory by Count* 1100 000w mod 101 r/m SS = SS segment register override prefix 0011 0110 2-2 STC = Set carry flag 1111 1001 4-228 data-8 Notes: * Indicates instructions not available in 8086 or 8088 systems. **Indicates instructions that are not supported with the necessary pinout. ***The external LOCK pin is only available on some members of the Am186 and Am188 family of microcontrollers. However, LOCK internal logic is still in effect on parts without the LOCK pin. A-8 Instruction Set Summary Table A-2 Instruction Set Summary by Mnemonic Instruction Opcode For More Info., See Page STD = Set direction flag 1111 1101 4-231 STI = Set interrupt-enable flag 1111 1011 4-235 STOS/STOSB/STOSW = Store string 1010 101w 4-237 SUB = Subtract: 4-240 Reg/memory and register to either 0010 10dw mod reg r/m Immediate from register/memory 1000 00sw mod 101 r/m data-8/data-low data-8/data-low data-high if w=1 data-high if sw=01 (sw≠10) Immediate from accumulator 0010 110w TEST = AND function to flags, no result: 4-243 Register/memory and register 1000 010w mod reg r/m Immediate data and register/mem. 1111 011w mod 000 r/m data-8/data-low Immediate data and accumulator 1010 100w data-8/data-low data-high if w=1 WAIT = Wait** 1001 1011 data-high if w=1 4-245 XCHG = Exchange: 4-246 Register/memory with register 1000 011w Register with accumulator 1 0 0 1 0 reg XLAT/XLATB = Translate byte to AL 1101 0111 mod reg r/m 4-248 XOR = Logical exclusive OR: 4-251 Reg/memory and register to either 0011 00dw mod reg r/m Immediate to register/memory 1000 00sw mod 110 r/m data-8/data-low data-8/data-low data-high if w=1 data-high if sw=01 (sw≠10) Immediate to accumulator 0011 010w Notes: * Indicates instructions not available in 8086 or 8088 systems. **Indicates instructions that are not supported with the necessary pinout. ***The external LOCK pin is only available on some members of the Am186 and Am188 family of microcontrollers. However, LOCK internal logic is still in effect on parts without the LOCK pin. Instruction Set Summary A-9 Table A-3 Instruction Set Summary by Opcode Opcode Byte 1 Hex Binary 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 0000 0000 0000 0001 0000 0010 0000 0011 0000 0100 0000 0101 0000 0110 0000 0111 0000 1000 0000 1001 0000 1010 0000 1011 0000 1100 0000 1101 0000 1110 0000 1111 0001 0000 0001 0001 0001 0010 0001 0011 0001 0100 0001 0101 0001 0110 0001 0111 0001 1000 0001 1001 0001 1010 0001 1011 0001 1100 0001 1101 0001 1110 0001 1111 0010 0000 0010 0001 0010 0010 0010 0011 0010 0100 0010 0101 0010 0110 27 28 29 0010 0111 0010 1000 0010 1001 A-10 Byte 2 Bytes 3–6 mod reg r/m mod reg r/m mod reg r/m mod reg r/m data-8 data-low (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) mod reg r/m mod reg r/m mod reg r/m mod reg r/m data-8 data-low (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) mod reg r/m mod reg r/m mod reg r/m mod reg r/m data-8 data-low (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) mod reg r/m mod reg r/m mod reg r/m mod reg r/m data-8 data-low (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) data-high data-high data-high data-high mod reg r/m mod reg r/m mod reg r/m mod reg r/m data-8 data-low (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) mod reg r/m mod reg r/m (disp-low),(disp-high) (disp-low),(disp-high) data-high Instruction Set Summary Instruction Format ADD r/m8,r8 ADD r/m16,r16 ADD r8,r/m8 ADD r16,r/m16 ADD AL,imm8 ADD AX,imm16 PUSH ES POP ES OR r/m8,r8 OR r/m16,r16 OR r8,r/m8 OR r16,r/m16 OR AL,imm8 OR AX,imm16 PUSH CS reserved ADC r/m8,r8 ADC r/m16,r16 ADC r8,r/m8 ADC r16,r/m16 ADC AL,imm8 ADC AX,imm16 PUSH SS POP SS SBB r/m8,r8 SBB r/m16,r16 SBB r8,r/m8 SBB r16,r/m16 SBB AL,imm8 SBB AX,imm16 PUSH DS POP DS AND r/m8,r8 AND r/m16,r16 AND r8,r/m8 AND r16,r/m16 AND AL,imm8 AND AX,imm16 (ES segment register override prefix) DAA SUB r/m8,r8 SUB r/m16,r16 Table A-3 Instruction Set Summary by Opcode Opcode Byte 1 Hex Binary 2A 2B 2C 2D 2E 0010 1010 0010 1011 0010 1100 0010 1101 0010 1110 2F 30 31 32 33 34 35 36 Byte 2 Bytes 3–6 mod reg r/m mod reg r/m data-8 data-low (disp-low),(disp-high) (disp-low),(disp-high) 0010 1111 0011 0000 0011 0001 0011 0010 0011 0011 0011 0100 0011 0101 0011 0110 mod reg r/m mod reg r/m mod reg r/m mod reg r/m data-8 data-low (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) 37 38 39 3A 3B 3C 3D 3E 0011 0111 0011 1000 0011 1001 0011 1010 0011 1011 0011 1100 0011 1101 0011 1110 mod reg r/m mod reg r/m mod reg r/m mod reg r/m data-8 data-low (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 0011 1111 0100 0000 0100 0001 0100 0010 0100 0011 0100 0100 0100 0101 0100 0110 0100 0111 0100 1000 0100 1001 0100 1010 0100 1011 0100 1100 0100 1101 0100 1110 0100 1111 0101 0000 0101 0001 0101 0010 data-high data-high data-high Instruction Set Summary Instruction Format SUB r8,r/m8 SUB r16,r/m16 SUB AL,imm8 SUB AX,imm16 (CS segment register override prefix) DAS XOR r/m8,r8 XOR r/m16,r16 XOR r8,r/m8 XOR r16,r/m16 XOR AL,imm8 XOR AX,imm16 (SS segment register override prefix) AAA CMP r/m8,r8 CMP r/m16,r16 CMP r8,r/m8 CMP r16,r/m16 CMP AL,imm8 CMP AX,imm16 (DS segment register override prefix) AAS INC AX INC CX INC DX INC BX INC SP INC BP INC SI INC DI DEC AX DEC CX DEC DX DEC BX DEC SP DEC BP DEC SI DEC DI PUSH AX PUSH CX PUSH DX A-11 Table A-3 Instruction Set Summary by Opcode Opcode Byte 1 Hex Binary Byte 2 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67 68 69 0101 0011 0101 0100 0101 0101 0101 0110 0101 0111 0101 1000 0101 1001 0101 1010 0101 1011 0101 1100 0101 1101 0101 1110 0101 1111 0110 0000 0110 0001 0110 0010 0110 0011 0110 0100 0110 0101 0110 0110 0110 0111 0110 1000 0110 1001 6A 6B 0110 1010 0110 1011 6C 0110 1100 6D 0110 1101 6E 0110 1110 6F 0110 1111 70 71 72 0111 0000 0111 0001 0111 0010 disp-8 disp-8 disp-8 73 0111 0011 disp-8 74 0111 0100 disp-8 A-12 Bytes 3–6 mod reg r/m (disp-low),(disp-high) data-low mod reg r/m data-high (disp-low),(disp-high),data-low, data-high data-8 mod reg r/m (disp-low),(disp-high),data-8 Instruction Set Summary Instruction Format PUSH BX PUSH SP PUSH BP PUSH SI PUSH DI POP AX POP CX POP DX POP BX POP SP POP BP POP SI POP DI PUSHA POPA BOUND r16,m16&16 reserved reserved reserved reserved reserved PUSH imm16 IMUL r16,r/m16,imm16 IMUL r16,imm16 PUSH imm8 IMUL r16,r/m16,imm8 IMUL r16,imm8 INS m8,DX INSB INS m16,DX INSW OUTS DX,r/m8 OUTSB OUTS DX,r/m16 OUTSW JO rel8 JNO rel8 JB rel8 JC rel8 JNAE rel8 JAE rel8 JNB rel8 JNC rel8 JE rel8 JZ rel8 Table A-3 Instruction Set Summary by Opcode Opcode Byte 1 Hex Binary Byte 2 Bytes 3–6 75 0111 0101 disp-8 76 0111 0110 disp-8 77 0111 0111 disp-8 78 79 7A 0111 1000 0111 1001 0111 1010 disp-8 disp-8 disp-8 7B 0111 1011 disp-8 7C 0111 1100 disp-8 7D 0111 1101 disp-8 7E 0111 1110 disp-8 7F 0111 1111 disp-8 80 1000 0000 81 1000 0001 mod 000 r/m mod 001 r/m mod 010 r/m mod 011 r/m mod 100 r/m mod 101 r/m mod 110 r/m mod 111 r/m mod 000 r/m mod 001 r/m mod 010 r/m mod 011 r/m mod 100 r/m mod 101 r/m mod 110 r/m mod 111 r/m (disp-low),(disp-high),data-8 (disp-low),(disp-high),data-8 (disp-low),(disp-high),data-8 (disp-low),(disp-high),data-8 (disp-low),(disp-high),data-8 (disp-low),(disp-high),data-8 (disp-low),(disp-high),data-8 (disp-low),(disp-high),data-8 (disp-low),(disp-high),data-low, data-high (disp-low),(disp-high),data-low, data-high (disp-low),(disp-high),data-low, data-high (disp-low),(disp-high),data-low, data-high (disp-low),(disp-high),data-low, data-high (disp-low),(disp-high),data-low, data-high (disp-low),(disp-high),data-low, data-high (disp-low),(disp-high),data-low, data-high 82 83 1000 0010 1000 0011 mod 000 r/m mod 001 r/m mod 010 r/m mod 011 r/m mod 100 r/m mod 101 r/m mod 110 r/m mod 111 r/m (disp-low),(disp-high),data-SX (disp-low),(disp-high),data-SX (disp-low),(disp-high),data-SX (disp-low),(disp-high),data-SX (disp-low),(disp-high),data-SX (disp-low),(disp-high),data-SX (disp-low),(disp-high),data-SX (disp-low),(disp-high),data-SX Instruction Set Summary Instruction Format JNE rel8 JNZ rel8 JBE rel8 JNA rel8 JA rel8 JNBE rel8 JS rel8 JNS rel8 JPE rel8 JP rel8 JPO rel8 JNP rel8 JL rel8 JNGE rel8 JGE rel8 JNL rel8 JLE rel8 JNG rel8 JG rel8 JNLE rel8 ADD r/m8,imm8 OR r/m8,imm8 ADC r/m8,imm8 SBB r/m8,imm8 AND r/m8,imm8 SUB r/m8,imm8 XOR r/m8,imm8 CMP r/m8,imm8 ADD r/m16,imm16 OR r/m16,imm16 ADC r/m16,imm16 SBB r/m16,imm16 AND r/m16,imm16 SUB r/m16,imm16 XOR r/m16,imm16 CMP r/m16,imm16 reserved ADD r/m16,imm8 OR r/m16,imm8 ADC r/m16,imm8 SBB r/m16,imm8 AND r/m16,imm8 SUB r/m16,imm8 XOR r/m16,imm8 CMP r/m16,imm8 A-13 Table A-3 Instruction Set Summary by Opcode Opcode Byte 1 Hex Binary Byte 2 Bytes 3–6 84 85 86 1000 0100 1000 0101 1000 0110 mod reg r/m mod reg r/m mod reg r/m (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) 87 1000 0111 mod reg r/m (disp-low),(disp-high) 88 89 8A 8B 8C 8D 8E 8F 90 1000 1000 1000 1001 1000 1010 1000 1011 1000 1100 1000 1101 1000 1110 1000 1111 1001 0000 mod reg r/m mod reg r/m mod reg r/m mod reg r/m mod 0 sreg r/m mod reg r/m mod 0 sreg r/m mod 000 r/m (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) 91 1001 0001 92 1001 0010 93 1001 0011 94 1001 0100 95 1001 0101 96 1001 0110 97 1001 0111 98 99 9A 9B 9C 9D 9E 9F A0 A1 A2 A3 A4 1001 1000 1001 1001 1001 1010 1001 1011 1001 1100 1001 1101 1001 1110 1001 1111 1010 0000 1010 0001 1010 0010 1010 0011 1010 0100 disp-low disp-high,seg-low,seg-high disp-low disp-low disp-low disp-low disp-high disp-high disp-high disp-high A-14 Instruction Set Summary Instruction Format TEST r/m8,r8 TEST r/m16,r16 XCHG r/m8,r8 XCHG r8,r/m8 XCHG r/m16,r16 XCHG r16,r/m16 MOV r/m8,r8 MOV r/m16,r16 MOV r8,r/m8 MOV r16,r/m16 MOV r/m16,sreg LEA r16,m16 MOV sreg,r/m16 POP m16 NOP XCHG AX,AX XCHG AX,CX XCHG CX,AX XCHG AX,DX XCHG DX,AX XCHG AX,BX XCHG BX,AX XCHG AX,SP XCHG SP,AX XCHG AX,BP XCHG BP,AX XCHG AX,SI XCHG SI,AX XCHG AX,DI XCHG DI,AX CBW CWD CALL ptr16:16 WAIT PUSHF POPF SAHF LAHF MOV AL,moffs8 MOV AX,moffs16 MOV moffs8,AL MOV moffs16,AX MOVS m8,m8 MOVSB Table A-3 Instruction Set Summary by Opcode Opcode Byte 1 Hex Binary A5 1010 0101 A6 1010 0110 A7 1010 0111 A8 A9 AA 1010 1000 1010 1001 1010 1010 AB 1010 1011 AC 1010 1100 AD 1010 1101 AE 1010 1110 AF 1010 1111 B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF C0 1011 0000 1011 0001 1011 0010 1011 0011 1011 0100 1011 0101 1011 0110 1011 0111 1011 1000 1011 1001 1011 1010 1011 1011 1011 1100 1011 1101 1011 1110 1011 1111 1100 0000 Byte 2 Bytes 3–6 data-8 data-low data-high data-8 data-8 data-8 data-8 data-8 data-8 data-8 data-8 data-low data-low data-low data-low data-low data-low data-low data-low mod 000 r/m mod 001 r/m mod 010 r/m mod 011 r/m mod 100 r/m data-high data-high data-high data-high data-high data-high data-high data-high (disp-low),(disp-high),data-8 (disp-low),(disp-high),data-8 (disp-low),(disp-high),data-8 (disp-low),(disp-high),data-8 (disp-low),(disp-high),data-8 mod 101 r/m mod 110 r/m mod 111 r/m (disp-low),(disp-high),data-8 (disp-low),(disp-high),data-8 Instruction Set Summary Instruction Format MOVS m16,m16 MOVSW CMPS m8,m8 CMPSB CMPS m16,m16 CMPSW TEST AL,imm8 TEST AX,imm16 STOS m8 STOSB STOS m16 STOSW LODS m8 LODSB LODS m16 LODSW SCAS m8 SCASB SCAS m16 SCASW MOV AL,imm8 MOV CL,imm8 MOV DL,imm8 MOV BL,imm8 MOV AH,imm8 MOV CH, imm8 MOV DH,imm8 MOV BH,imm8 MOV AX,imm16 MOV CX,imm16 MOV DX,imm16 MOV BX,imm16 MOV SP,imm16 MOV BP,imm16 MOV SI,imm16 MOV DI,imm16 ROL r/m8,imm8 ROR r/m8,imm8 RCL r/m8,imm8 RCR r/m8,imm8 SAL r/m8,imm8 SHL r/m8,imm8 SHR r/m8,imm8 reserved SAR r/m8,imm8 A-15 Table A-3 Instruction Set Summary by Opcode Opcode Byte 1 Hex Binary C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF D0 D1 1100 0001 1100 0010 1100 0011 1100 0100 1100 0101 1100 0110 1100 0111 1100 1000 1100 1001 1100 1010 1100 1011 1100 1100 1100 1101 1100 1110 1100 1111 1101 0000 1101 0001 Byte 2 mod 000 r/m mod 001 r/m mod 010 r/m mod 011 r/m mod 100 r/m (disp-low),(disp-high),data-8 (disp-low),(disp-high),data-8 (disp-low),(disp-high),data-8 (disp-low),(disp-high),data-8 (disp-low),(disp-high),data-8 mod 101 r/m mod 110 r/m mod 111 r/m data-low (disp-low),(disp-high),data-8 (disp-low),(disp-high),data-8 data-high mod reg r/m mod reg r/m mod 000 r/m mod 000 r/m data-low (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high),data-8 (disp-low),(disp-high),data-low, data-high data-high, data-8 data-low data-high data-8 mod 000 r/m mod 001 r/m mod 010 r/m mod 011 r/m mod 100 r/m (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) mod 101 r/m mod 110 r/m mod 111 r/m mod 000 r/m mod 001 r/m mod 010 r/m mod 011 r/m mod 100 r/m (disp-low),(disp-high) mod 101 r/m mod 110 r/m mod 111 r/m A-16 Bytes 3–6 (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) Instruction Set Summary Instruction Format ROL r/m16,imm8 ROR r/m16,imm8 RCL r/m16,imm8 RCR r/m16,imm8 SAL r/m16,imm8 SHL r/m16,imm8 SHR r/m16,imm8 reserved SAR r/m16,imm8 RET imm16 RET LES r16,m16:16 LDS r16,m16:16 MOV r/m8,imm8 MOV r/m16,imm16 ENTER imm16,imm8 LEAVE RET imm16 RET INT 3 INT imm8 INTO IRET ROL r/m8,1 ROR r/m8,1 RCL r/m8,1 RCR r/m8,1 SAL r/m8,1 SHL r/m8,1 SHR r/m8,1 reserved SAR r/m8,1 ROL r/m16,1 ROR r/m16,1 RCL r/m16,1 RCR r/m16,1 SAL r/m16,1 SHL r/m16,1 SHR r/m16,1 reserved SAR r/m16,1 Table A-3 Instruction Set Summary by Opcode Opcode Byte 1 Hex Binary D2 D3 1101 0010 1101 0011 Byte 2 Bytes 3–6 mod 000 r/m mod 001 r/m mod 010 r/m mod 011 r/m mod 100 r/m (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) mod 101 r/m mod 110 r/m mod 111 r/m mod 000 r/m mod 001 r/m mod 010 r/m mod 011 r/m mod 100 r/m (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) mod 101 r/m mod 110 r/m mod 111 r/m 0000 1010 0000 1010 (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) D4 D5 D6 D7 1101 0100 1101 0101 1101 0110 1101 0111 D8 D9 DA DB DC DD DE DF E0 1101 1000 1101 1001 1101 1010 1101 1011 1101 1100 1101 1101 1101 1110 1101 1111 1110 0000 mod 000 r/m mod 001 r/m mod 010 r/m mod 011 r/m mod 100 r/m mod 101 r/m mod 110 r/m mod 111 r/m disp-8 E1 1110 0001 disp-8 E2 E3 E4 E5 E6 E7 E8 E9 EA 1110 0010 1110 0011 1110 0100 1110 0101 1110 0110 1110 0111 1110 1000 1110 1001 1110 1010 disp-8 disp-8 data-8 data-8 data-8 data-8 disp-low disp-low disp-low (disp-low),(disp-high) disp-high disp-high disp-high,seg-low,seg-high Instruction Set Summary Instruction Format ROL r/m8,CL ROR r/m8,CL RCL r/m8,CL RCR r/m8,CL SAL r/m8,CL SHL r/m8,CL SHR r/m8,CL reserved SAR r/m8,CL ROL r/m16,CL ROR r/m16,CL RCL r/m16,CL RCR r/m16,CL SAL r/m16,CL SHL r/m16,CL SHR r/m16,CL reserved SAR r/m16,CL AAM AAD reserved XLAT m8 XLATB ESC m ESC m ESC m ESC m ESC m ESC m ESC m ESC m LOOPNE rel8 LOOPNZ rel8 LOOPE rel8 LOOPZ rel8 LOOP rel8 JCXZ rel8 IN AL,imm8 IN AX,imm8 OUT imm8,AL OUT imm8,AX CALL rel16 JMP rel16 JMP ptr16:16 A-17 Table A-3 Instruction Set Summary by Opcode Opcode Byte 1 Hex Binary EB EC ED EE EF F0 F1 F2 1110 1011 1110 1100 1110 1101 1110 1110 1110 1111 1111 0000 1111 0001 1111 0010 Byte 2 Bytes 3–6 disp-8 1010 0110 1010 0111 1010 1110 1010 1111 F3 1111 0011 0110 1100 0110 1101 0110 1110 0110 1111 1010 0100 1010 0101 1010 0110 1010 0111 1010 1010 1010 1011 1010 1100 1010 1101 1010 1110 1010 1111 F4 F5 F6 A-18 1111 0100 1111 0101 1111 0110 mod 000 r/m mod 001 r/m mod 010 r/m mod 011 r/m mod 100 r/m mod 101 r/m mod 110 r/m mod 111 r/m (disp-low),(disp-high),data-8 (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) Instruction Set Summary Instruction Format JMP rel8 IN AL,DX IN AX,DX OUT DX,AL OUT DX,AX LOCK (prefix) reserved REPNE CMPS m8,m8 REPNZ CMPS m8,m8 REPNE CMPS m16,m16 REPNZ CMPS m16,m16 REPNE SCAS m8 REPNZ SCAS m8 REPNE SCAS m16 REPNZ SCAS m16 REP INS r/m8,DX REP INS r/m16,DX REP OUTS DX,r/m8 REP OUTS DX,r/m16 REP MOVS m8,m8 REP MOVS m16,m16 REPE CMPS m8,m8 REPZ CMPS m8,m8 REPE CMPS m16,m16 REPZ CMPS m16,m16 REP STOS m8 REP STOS m16 REP LODS m8 REP LODS m16 REPE SCAS m8 REPZ SCAS m8 REPE SCAS m16 REPZ SCAS m16 HLT CMC TEST r/m8,imm8 reserved NOT r/m8 NEG r/m8 MUL r/m8 IMUL r/m8 DIV r/m8 IDIV r/m8 Table A-3 Instruction Set Summary by Opcode Opcode Byte 1 Hex Binary F7 1111 0111 F8 F9 FA FB FC FD FE 1111 1000 1111 1001 1111 1010 1111 1011 1111 1100 1111 1101 1111 1110 FF 1111 1111 Byte 2 Bytes 3–6 mod 000 r/m mod 001 r/m mod 010 r/m mod 011 r/m mod 100 r/m mod 101 r/m mod 110 r/m mod 111 r/m (disp-low),(disp-high),data-low, data-high mod 000 r/m mod 001 r/m mod 010 r/m mod 011 r/m mod 100 r/m mod 101 r/m mod 110 r/m mod 111 r/m mod 000 r/m mod 001 r/m mod 010 r/m mod 011 r/m mod 100 r/m mod 101 r/m mod 110 r/m mod 111 r/m (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) (disp-low),(disp-high) Instruction Set Summary Instruction Format TEST r/m16,imm16 reserved NOT r/m16 NEG r/m16 MUL r/m16 IMUL r/m16 DIV r/m16 IDIV r/m16 CLC STC CLI STI CLD STD INC r/m8 DEC r/m8 reserved reserved reserved reserved reserved reserved INC r/m16 DEC r/m16 CALL r/m16 CALL m16:16 JMP r/m16 JMP m16:16 PUSH m16 reserved A-19 Instruction Set Summary by Partial Opcode x0 x1 x2 x3 x4 x5 x6 x7 O pc od e Table A-4 0x 1x ADD ADD ADD ADD ADD ADD PUSH POP r/m8,r8 r/m16,r16 r8,r/m8 r16,r/m16 AL,imm8 AX,imm16 ES ES ADC ADC ADC ADC ADC ADC PUSH POP r/m8,r8 r/m16,r16 r8,r/m8 r16,r/m16 AL,imm8 AX,imm16 SS SS (ES seg. reg. override prefix) DAA AND AND AND AND AND AND 2x r/m8,r8 r/m16,r16 r8,r/m8 r16,r/m16 AL,imm8 AX,imm16 XOR XOR XOR XOR XOR XOR r/m8,r8 r/m16,r16 r8,r/m8 r16,r/m16 AL,imm8 AX,imm16 (SS seg. reg. override prefix) AAA 3x INC INC INC INC INC INC INC INC AX CX DX BX SP BP SI DI PUSH PUSH PUSH PUSH PUSH PUSH PUSH PUSH AX CX DX BX SP BP SI DI PUSHA POPA BOUND (reserved) (reserved) (reserved) (reserved) (reserved) 4x 5x 6x 7x r16,m16&16 JO JNO JB/JC/JNAE JAE/JNB/JNC JE/JZ JNE/JNZ JBE/JNA JA/JNBE rel8 rel8 rel8 rel8 rel8 rel8 rel8 rel8 Immed Immed (reserved) r/m8,imm8 r/m16,imm16 Immed TEST TEST XCHG XCHG r/m16,imm8 r/m8,r8 r/m16,r16 r/m8,r8 r/m16,r16 8x NOP 9x Bx Cx Dx XCHG r8,r/m8 r16,r/m16 XCHG XCHG XCHG XCHG XCHG XCHG XCHG AX,CX AX,DX AX,BX AX,SP AX,BP AX,SI AX,DI’ XCHG XCHG XCHG XCHG XCHG XCHG XCHG CX,AX DX,AX BX,AX SP,AX BP,AX SI,AX DI,AX XCHG AX,AX Ax XCHG MOV MOV MOV MOV MOVS MOVS CMPS CMPS AL,moffs8 AX,moffs16 moffs8,AL moffs16,AX m8,m8 m16,m16 m8,m8 m16,m16 MOVSB MOVSW CMPSB CMPSW MOV MOV MOV MOV MOV MOV MOV MOV AL,imm8 CL,imm8 DL,imm8 BL,imm8 AH,imm8 CH, imm8 DH,imm8 BH,imm8 RET Shift Shift RET r/m8,imm8 r/m16,imm8 imm16 Shift Shift Shift Shift r/m8,1 r/m16,1 r/m8,CL r/m16,CL LES LDS MOV MOV r16,m16:16 r16,m16:16 r/m8,imm8 r/m16,imm16 AAM AAD (reserved) XLAT m8 XLATB Ex Fx A-20 LOOPNE/ LOOPNZ LOOPE/ LOOPZ rel8 rel8 LOCK (prefix) (reserved) LOOP JCXZ IN IN OUT OUT rel8 rel8 AL,imm8 AX,imm8 imm8,AL imm8,AX REPNE/ REPNZ (prefix) REP/REPE/ REPZ (prefix) HLT CMC Instr1 Instr1 r/m8 r/m16 Instruction Set Summary Instruction Set Summary by Partial Opcode (continued) x8 x9 xA xB xC xD xE xF (reserved) O pc od e Table A-4 0x 1x OR OR OR OR OR OR PUSH r/m8,r8 r/m16,r16 r8,r/m8 r16,r/m16 AL,imm8 AX,imm16 CS SBB SBB SBB SBB SBB SBB PUSH POP r/m8,r8 r/m16,r16 r8,r/m8 r16,r/m16 AL,imm8 AX,imm16 DS DS (CS seg. reg. override prefix) DAS SUB SUB SUB SUB SUB SUB 2x r/m8,r8 r/m16,r16 r8,r/m8 r16,r/m16 AL,imm8 AX,imm16 CMP CMP CMP CMP CMP CMP r/m8,r8 r/m16,r16 r8,r/m8 r16,r/m16 AL,imm8 AX,imm16 (DS seg. reg. override prefix) AAS 3x DEC DEC DEC DEC DEC DEC DEC DEC AX CX DX BX SP BP SI DI POP POP POP POP POP POP POP POP AX CX DX BX SP BP SI DI PUSH IMUL PUSH IMUL INS INS OUTS OUTS imm16 r16,r/m16,imm16 imm8 r16,r/m16,imm8 m8,DX m16,DX DX,r/m8 DX,r/m16 IMUL IMUL INSB INSW OUTSB OUTSW r16,imm16 r16,imm8 4x 5x 6x 7x 8x 9x Ax Bx Cx Dx Ex Fx JS JNS JPE/JP JPO/JNP JL/JNGE JGE/JNL JLE/JNG JG/JNLE rel8 rel8 rel8 rel8 rel8 rel8 rel8 rel8 MOV MOV MOV MOV MOV LEA MOV POP r/m8,r8 r/m16,r16 r8,r/m8 r16,r/m16 r/m16,sreg r16,m16 sreg,r/m16 m16 CBW CWD CALL WAIT PUSHF POPF SAHF LAHF ptr16:16 TEST TEST STOS STOS LODS LODS SCAS SCAS AL,imm8 AX,imm16 m8 m16 m8 m16 m8 m16 STOSB STOSW LODSB LODSW SCASB SCASW MOV MOV MOV MOV MOV MOV MOV MOV AX,imm16 CX,imm16 DX,imm16 BX,imm16 SP,imm16 BP,imm16 SI,imm16 DI,imm16 ENTER LEAVE RET RET INT 3 INT INTO IRET imm16,imm8 imm16 imm8 ESC ESC ESC ESC ESC ESC ESC ESC m m m m m m m m CALL JMP JMP JMP IN IN OUT OUT rel16 rel16 ptr16:16 rel8 AL,DX AX,DX DX,AL DX,AX CLC STC CLI STI CLD STD Instr2 Instr3 r/m8 Instruction Set Summary A-21 Table A-5 Abbreviations for Table A-4 Instruction Group Immed Shift Instr1 Instr2 Instr3 Byte 2 mod 000 r/m ADD ROL TEST INC INC r/m16 mod 001 r/m OR ROR mod 010 r/m ADC RCL (reserved) DEC DEC r/m16 NOT (reserved) CALL r/m16 mod 011 r/m SBB RCR NEG (reserved) CALL m16:16 mod 100 r/m AND SAL/SHL MUL (reserved) JMP r/m16 mod 101 r/m SUB SHR IMUL (reserved) JMP m16:16 mod 110 r/m XOR (reserved) DIV (reserved) PUSH m16 mod 111 r/m CMP SAR IDIV (reserved) (reserved) Note: mod and r/m determine the Effective Address (EA) calculation. See Table A-1 for definitions. A-22 Instruction Set Summary INDEX A SAL (Shift Arithmetic Left) instruction, 4-211 SAR (Shift Arithmetic Right) instruction, 4-214 SBB (Subtract Numbers with Borrow) instruction, 4-216 SHL (Shift Left) instruction, 4-211, 4-224 SHR (Shift Right) instruction, 4-225 SUB (Subtract Numbers) instruction, 4-240 AAA (ASCII Adjust AL after Addition) instruction, 4-2 AAD (ASCII Adjust AX before Division) instruction, 4-4 AAM (ASCII Adjust AL after Multiplication) instruction, 4-6 AAS (ASCII Adjust AL after Subtraction) instruction, 4-8 abbreviations for partial opcode table, A-22 ADC (Add Numbers with Carry) instruction, 4-10 ADD (Add Numbers) instruction, 4-14 address calculation and translation instructions LDS (Load DS with Segment and Register with Offset) instruction, 4-131 LEA (Load Effective Address) instruction, 4-133 LES (Load ES with Segment and Register with Offset) instruction, 4-138 list of, 3-1 XLAT (Translate Table Index to Component) instruction, 4-248 XLATB (Translate Table Index to Byte) instruction, 4-248 block-structured language instructions ENTER (Enter High-Level Procedure) instruction, 4-53 LEAVE (Leave High-Level Procedure) instruction, 4-135 list of, 3-3 BOUND (Check Array Index Against Bounds) instruction, 4-19 C CALL (Call Procedure) instruction, 4-21 CBW (Convert Byte Integer to Word) instruction, 4-24 CLC (Clear Carry Flag) instruction, 4-26 CLD (Clear Direction Flag) instruction, 4-29 addressing modes, 1-7 memory operands, 1-7 register and immediate operands, 1-7 register indirect mode, 1-7 CLI (Clear Interrupt-Enable Flag) instruction, 4-31 CMC (Complement Carry Flag) instruction, 4-33 CMP (Compare Components) instruction, 4-34 addressing notation, 2-3 CMPS (Compare String Components) instruction, 4-36 AND (Logical AND) instruction, 4-17 CMPSB (Compare String Bytes) instruction, 4-36 CMPSW (Compare String Words) instruction, 4-36 B base and index registers, 1-1 binary arithmetic instructions ADC (Add Numbers with Carry) instruction, 4-10 ADD (Add Numbers) instruction, 4-14 CBW (Convert Byte Integer to Word) instruction, 4-24 CWD (Convert Word Integer to Doubleword) instruction, 4-40 DEC (Decrement Number by One) instruction, 4-48 DIV (Divide Unsigned Numbers) instruction, 4-50 IDIV (Divide Integers) instruction, 4-60 IMUL (Multiply Integers) instruction, 4-63 INC (Increment Number by One) instruction, 4-69 list of, 3-2 MUL (Multiply Unsigned Numbers) instruction, 4-160 NEG (Two’s Complement Negation) instruction, 4-163 comparison instructions CMP (Compare Components) instruction, 4-34 CMPS (Compare String Components) instruction, 4-36 CMPSB (Compare String Bytes) instruction, 4-36 CMPSW (Compare String Words) instruction, 4-36 list of, 3-3 SCAS (Scan String for Component) instruction, 4-219 SCASB (Scan String for Byte) instruction, 4-219 SCASW (Scan String for Word) instruction, 4-219 TEST (Logical Compare) instruction, 4-243 control transfer instructions BOUND (Check Array Index Against Bounds) instruction, 4-19 CALL (Call Procedure) instruction, 4-21 IDIV (Divide Integers) instruction, 4-60 Index I-1 INT (Generate Interrupt) instruction, 4-73 INTO (Generate Interrupt If Overflow) instruction, 4-73 IRET (Interrupt Return) instruction, 4-76 JA (Jump If Above) instruction, 4-78 JAE (Jump If Above or Equal) instruction, 4-80 JB (Jump If Below) instruction, 4-82 JBE (Jump If Below or Equal) instruction, 4-84 JC (Jump If Carry) instruction, 4-82 JCXZ (Jump If CX Register Is Zero) instruction, 4-87 JE (Jump If Equal) instruction, 4-89 JG (Jump If Greater) instruction, 4-91 JGE (Jump If Greater or Equal) instruction, 4-93 JL (Jump If Less) instruction, 4-95 JLE (Jump If Less or Equal) instruction, 4-97 JMP (Jump) instruction, 4-99 JNA (Jump If Not Above) instruction, 4-84 JNAE (Jump If Not Above or Equal) instruction, 4-82 JNB (Jump If Not Below) instruction, 4-80 JNBE (Jump If Not Below or Equal) instruction, 4-78 JNC (Jump If Not Carry) instruction, 4-80 JNE (Jump If Not Equal) instruction, 4-107 JNG (Jump If Not Greater) instruction, 4-97 JNGE (Jump If Not Greater or Equal) instruction, 4-95 JNL (Jump If Not Less) instruction, 4-93 JNLE (Jump If Not Less or Equal) instruction, 4-91 JNO (Jump If Not Overflow) instruction, 4-113 JNP (Jump If Not Parity) instruction, 4-124 JNS (Jump If Not Sign) instruction, 4-116 JNZ (Jump If Not Zero) instruction, 4-107 JO (Jump If Overflow) instruction, 4-119 JP (Jump If Parity) instruction, 4-122 JPE (Jump If Parity Even) instruction, 4-122 JPO (Jump If Parity Odd) instruction, 4-124 JS (Jump If Sign) instruction, 4-126 JZ (Jump If Zero) instruction, 4-89 list of, 3-3 LOOP (Loop While CX Register Is Not Zero) instruction, 4-146 LOOPE (Loop If Equal) instruction, 4-148 LOOPNE (Loop If Not Equal) instruction, 4-150 LOOPNZ (Loop If Not Zero) instruction, 4-150 LOOPZ (Loop If Zero) instruction, 4-148 RET (Return from Procedure) instruction, 4-202 CWD (Convert Word Integer to Doubleword) instruction, 4-40 D DAA (Decimal Adjust AL after Addition) instruction, 4-42 DAS (Decimal Adjust AL after Subtraction) instruction, 4-45 data movement instructions IN (Input Component from Port) instruction, 4-67 INS (Input String Component from Port) instruction, 4-71 INSB (Input String Byte from Port) instruction, 4-71 INSW (Input String Word from Port) instruction, 4-71 I-2 LAHF (Load AH with Flags) instruction, 4-129 list of, 3-5 LODS (Load String Component) instruction, 4-141 LODSB (Load String Byte) instruction, 4-141 LODSW (Load String Word) instruction, 4-141 MOV (Move Component) instruction, 4-153 MOVS (Move String Component) instruction, 4-156 MOVSB (Move String Byte) instruction, 4-156 MOVSW (Move String Word) instruction, 4-156 OUT (Output Component to Port) instruction, 4-171 OUTS (Output String Component to Port) instruction, 4-173 OUTSB (Output String Byte to Port) instruction, 4-173 OUTSW (Output String Word to Port) instruction, 4-173 POP (Pop Component from Stack) instruction, 4-175 POPA (Pop All 16-Bit General Registers from Stack) instruction, 4-178 POPF (Pop Flags from Stack) instruction, 4-180 PUSH (Push Component onto Stack) instruction, 4-181 PUSHA (Push All 16-Bit General Registers onto Stack) instruction, 4-184 PUSHF (Push Flags onto Stack) instruction, 4-186 SAHF (Store AH in Flags) instruction, 4-209 STOS (Store String Component) instruction, 4-237 STOSB (Store String Byte) instruction, 4-237 STOSW (Store String Word) instruction, 4-237 XCHG (Exchange Components) instruction, 4-246 data types ASCII, 1-6 BCD, 1-5 double word, 1-5 integer, 1-5 ordinal, 1-5 packed BCD, 1-6 pointer, 1-6 quad word, 1-5 string, 1-6 supported data types, 1-6 DEC (Decrement Number by One) instruction, 4-48 decimal arithmetic instructions AAA (ASCII Adjust AL after Addition) instruction, 4-2 AAD (ASCII Adjust AX before Division) instruction, 4-4 AAM (ASCII Adjust AL after Multiplication) instruction, 4-6 AAS (ASCII Adjust AL after Subtraction) instruction, 4-8 ADD (Add Numbers) instruction, 4-14 DAA (Decimal Adjust AL after Addition) instruction, 4-42 DAS (Decimal Adjust AL after Subtraction) instruction, 4-45 DIV (Divide Unsigned Numbers) instruction, 4-50 list of, 3-6 MUL (Multiply Unsigned Numbers) instruction, 4-160 SUB (Subtract Numbers) instruction, 4-240 development tools Index third-party products, iv OUT (Output Component to Port) instruction, 4-171 OUTS (Output String Component to Port) instruction, 4-173 OUTSB (Output String Byte to Port) instruction, 4-173 OUTSW (Output String Word to Port) instruction, 4-173 DIV (Divide Unsigned Numbers) instruction, 4-50 documentation AMD E86 Family publications, iv INS (Input String Component from Port) instruction, 4-71 E INSB (Input String Byte from Port) instruction, 4-71 ENTER (Enter High-Level Procedure) instruction, 4-53 ESC (Escape) instruction, 4-56 F instruction format, 2-1 instruction prefixes, 2-1 opcode, 2-2 operand address, 2-2 segment override prefix, 2-1 instruction forms table sample, 2-4 flag instructions CLC (Clear Carry Flag) instruction, 4-26 CLD (Clear Direction Flag) instruction, 4-29 CLI (Clear Interrupt-Enable Flag) instruction, 4-31 CMC (Complement Carry Flag) instruction, 4-33 list of, 3-7 POPF (Pop Flags from Stack) instruction, 4-180 RCL (Rotate through Carry Left) instruction, 4-187 RCR (Rotate through Carry Right) instruction, 4-189 SAHF (Store AH in Flags) instruction, 4-209 STC (Set Carry Flag) instruction, 4-228 STD (Set Direction Flag) instruction, 4-231 STI (Set Interrupt-Enable Flag) instruction, 4-235 instruction set, 1-3 alphabetical order list, 3-11 by type, 3-1 summary table by mnemonic, A-3– A-9 summary table by opcode, A-10– A-19 summary table by partial opcode A-20–, A-21 INSW (Input String Word from Port) instruction, 4-71 INT (Generate Interrupt) instruction, 4-73 INTO (Generate Interrupt If Overflow) instruction, 4-73 IRET (Interrupt Return) instruction, 4-76 J G JA (Jump If Above) instruction, 4-78 general registers base and index registers, 1-1 description of, 1-1 stack pointer register, 1-1 JAE (Jump If Above or Equal) instruction, 4-80 JB (Jump If Below) instruction, 4-82 JBE (Jump If Below or Equal) instruction, 4-84 JC (Jump If Carry) instruction, 4-82 H JCXZ (Jump If CX Register Is Zero) instruction, 4-87 HLT (Halt) instruction, 4-57 JE (Jump If Equal) instruction, 4-89 JG (Jump If Greater) instruction, 4-91 I JGE (Jump If Greater or Equal) instruction, 4-93 I/O space description of, 1-5 JL (Jump If Less) instruction, 4-95 IDIV (Divide Integers) instruction, 4-60 JMP (Jump) instruction, 4-99 IMUL (Multiply Integers) instruction, 4-63 JNA (Jump If Not Above) instruction, 4-84 IN (Input Component from Port) instruction, 4-67 JNAE (Jump If Not Above or Equal) instruction, 4-82 INC (Increment Number by One) instruction, 4-69 JNB (Jump If Not Below) instruction, 4-80 input/output instructions IN (Input Component from Port) instruction, 4-67 INS (Input String Component from Port) instruction, 4-71 INSB (Input String Byte from Port) instruction, 4-71 INSW (Input String Word from Port) instruction, 4-71 list of, 3-8 JNBE (Jump If Not Below or Equal) instruction, 4-78 JLE (Jump If Less or Equal) instruction, 4-97 JNC (Jump If Not Carry) instruction, 4-80 JNE (Jump If Not Equal) instruction, 4-107 JNG (Jump If Not Greater) instruction, 4-97 JNGE (Jump If Not Greater or Equal) instruction, 4-95 Index I-3 M JNL (Jump If Not Less) instruction, 4-93 JNLE (Jump If Not Less or Equal) instruction, 4-91 memory addressing modes based indexed mode, 1-7 based indexed mode with displacement, 1-7 based mode, 1-7 direct mode, 1-7 examples, 1-7 indexed mode, 1-7 JNO (Jump If Not Overflow) instruction, 4-113 JNP (Jump If Not Parity) instruction, 4-124 JNS (Jump If Not Sign) instruction, 4-116 JNZ (Jump If Not Zero) instruction, 4-107 JO (Jump If Overflow) instruction, 4-119 memory and I/O space, 1-4 JP (Jump If Parity) instruction, 4-122 JS (Jump If Sign) instruction, 4-126 memory operands, 1-7 base, 1-7 displacement, 1-7 index, 1-7 JZ (Jump If Zero) instruction, 4-89 MOV (Move Component) instruction, 4-153 JPE (Jump If Parity Even) instruction, 4-122 JPO (Jump If Parity Odd) instruction, 4-124 MOVS (Move String Component) instruction, 4-156 MOVSB (Move String Byte) instruction, 4-156 L MOVSW (Move String Word) instruction, 4-156 LAHF (Load AH with Flags) instruction, 4-129 MUL (Multiply Unsigned Numbers) instruction, 4-160 LDS (Load DS with Segment and Register with Offset) instruction, 4-131 N LEA (Load Effective Address) instruction, 4-133 LEAVE (Leave High-Level Procedure) instruction, 4-135 NEG (Two’s Complement Negation) instruction, 4-163 LES (Load ES with Segment and Register with Offset) instruction, 4-138 NOP (No Operation) instruction, 4-165 NOT (One’s Complement Negation) instruction, 4-167 LOCK (Lock the Bus) instruction, 4-140 LODS (Load String Component) instruction, 4-141 O LODSB (Load String Byte) instruction, 4-141 LODSW (Load String Word) instruction, 4-141 opcode, 2-5 logical operation instructions AND (Logical AND) instruction, 4-17 list of, 3-8 NOT (One’s Complement Negation) instruction, 4-167 OR (Logical Inclusive OR) instruction, 4-169 RCL (Rotate through Carry Left) instruction, 4-187 RCR (Rotate through Carry Right) instruction, 4-189 ROL (Rotate Left) instruction, 4-205 ROR (Rotate Right) instruction, 4-207 SAL (Shift Arithmetic Left) instruction, 4-211 SAR (Shift Arithmetic Right) instruction, 4-214 SHL (Shift Left) instruction, 4-211, 4-224 SHR (Shift Right) instruction, 4-225 XOR (Logical Exclusive OR) instruction, 4-251 operand address aux field, 2-3 displacement, 2-3 immediate, 2-3 mod field, 2-2 r/m field, 2-3 LOOP (Loop While CX Register Is Not Zero) instruction, 4-146 overview instruction set, 2-1 OR (Logical Inclusive OR) instruction, 4-169 OUT (Output Component to Port) instruction, 4-171 OUTS (Output String Component to Port) instruction, 4-173 OUTSB (Output String Byte to Port) instruction, 4-173 OUTSW (Output String Word to Port) instruction, 4-173 LOOPE (Loop If Equal) instruction, 4-148 P LOOPNE (Loop If Not Equal) instruction, 4-150 LOOPNZ (Loop If Not Zero) instruction, 4-150 physical-address generation, 1-4 LOOPZ (Loop If Zero) instruction, 4-148 POP (Pop Component from Stack) instruction, 4-175 I-4 Index POPA (Pop All 16-Bit General Registers from Stack) instruction, 4-178 extra segment (ES), 1-5 segment register selection rules, 1-5 stack segment (SS), 1-5 POPF (Pop Flags from Stack) instruction, 4-180 SHL (Shift Left) instruction, 4-211, 4-224 processor control instructions ESC (Escape) instruction, 4-56 HLT (Halt) instruction, 4-57 list of, 3-9 LOCK (Lock the Bus) instruction, 4-140 NOP (No Operation) instruction, 4-165 WAIT (Wait for Coprocessor) instruction, 4-245 SHR (Shift Right) instruction, 4-225 stack pointer register, 1-1 status and control registers, 1-1 STC (Set Carry Flag) instruction, 4-228 STD (Set Direction Flag) instruction, 4-231 processor status flags register, 1-2 PUSH (Push Component onto Stack) instruction, 4-181 PUSHA (Push All 16-Bit General Registers onto Stack) instruction, 4-184 STI (Set Interrupt-Enable Flag) instruction, 4-235 STOS (Store String Component) instruction, 4-237 STOSB (Store String Byte) instruction, 4-237 STOSW (Store String Word) instruction, 4-237 PUSHF (Push Flags onto Stack) instruction, 4-186 SCAS (Scan String for Component) instruction, 4-219 string instructions CLD (Clear Direction Flag) instruction, 4-29 CMPS (Compare String Components) instruction, 4-36 CMPSB (Compare String Bytes) instruction, 4-36 CMPSW (Compare String Words) instruction, 4-36 INS (Input String Component from Port) instruction, 4-71 INSB (Input String Byte from Port) instruction, 4-71 INSW (Input String Word from Port) instruction, 4-71 list of, 3-9 LODS (Load String Component) instruction, 4-141 LODSB (Load String Byte) instruction, 4-141 LODSW (Load String Word) instruction, 4-141 MOVS (Move String Component) instruction, 4-156 MOVSB (Move String Byte) instruction, 4-156 MOVSW (Move String Word) instruction, 4-156 OUTS (Output String Component to Port) instruction, 4-173 OUTSB (Output String Byte to Port) instruction, 4-173 OUTSW (Output String Word to Port) instruction, 4-173 REP (Repeat) instruction, 4-191 REPE (Repeat While Equal) instruction, 4-193 REPNE (Repeat While Not Equal) instruction, 4-197 REPNZ (Repeat While Not Zero) instruction, 4-197 REPZ (Repeat While Zero) instruction, 4-193, 4-201 SCAS (Scan String for Component) instruction, 4-219 SCASB (Scan String for Byte) instruction, 4-219 SCASW (Scan String for Word) instruction, 4-219 STD (Set Direction Flag) instruction, 4-231 STOS (Store String Component) instruction, 4-237 STOSB (Store String Byte) instruction, 4-237 STOSW (Store String Word) instruction, 4-237 SCASB (Scan String for Byte) instruction, 4-219 SUB (Subtract Numbers) instruction, 4-240 R RCL (Rotate through Carry Left) instruction, 4-187 RCR (Rotate through Carry Right) instruction, 4-189 register and immediate operands, 1-7 register set, 1-2 general registers, 1-1 segment registers, 1-1 status and control registers, 1-1 REP (Repeat) instruction, 4-191 REPE (Repeat While Equal) instruction, 4-193 REPNE (Repeat While Not Equal) instruction, 4-197 REPNZ (Repeat While Not Zero) instruction, 4-197 REPZ (Repeat While Zero) instruction, 4-193, 4-201 RET (Return from Procedure) instruction, 4-202 ROL (Rotate Left) instruction, 4-205 ROR (Rotate Right) instruction, 4-207 S SAHF (Store AH in Flags) instruction, 4-209 SAL (Shift Arithmetic Left) instruction, 4-211 SAR (Shift Arithmetic Right) instruction, 4-214 SBB (Subtract Numbers with Borrow) instruction, 4-216 SCASW (Scan String for Word) instruction, 4-219 segment registers, 1-1 segments code segment (CS), 1-5 data segment (DS), 1-5 Index I-5 summary tables abbreviations for partial opcode table, A-22 instruction set summary by mnemonic, A-3–, A-9 instruction set summary by opcode, A-10–, A-19 instruction set summary by partial opcode, A-20–, A-21 variables used in instruction set, A-2 T TEST (Logical Compare) instruction, 4-243 U using this manual, 2-4 description, 2-6 examples, 2-7 flag settings after instruction, 2-7 forms of the instruction, 2-4 mnemonics, 2-4 sample, 2-4 names sample, 2-4 operations, 2-7 related instructions, 2-8 syntax, 2-6 tips, 2-8 V variables used in instruction set summary tables, A-2 W WAIT (Wait for Coprocessor) instruction, 4-245 X XCHG (Exchange Components) instruction, 4-246 XLAT (Translate Table Index to Component) instruction, 4-248 XLATB (Translate Table Index to Byte) instruction, 4-248 XOR (Logical Exclusive OR) instruction, 4-251 I-6 Index