You are on page 1of 114
16 = Assembly Language Reference Guide @ About the Reference, 704 © Protected-Mode Instructions, 704 © Going co the Source, 704 © Instruction Timings and Binary Encodings, 705 @ How to Use the Reference, 706 16 tise cee 704 About the Reference This chapter lists all 8086, 8088, 80286, 80386, 80486, and Pentium non-protected-mode ‘mnemonics in alphabetic order, showing the affected flags listing the syntax forall inseruc- tion forms, and giving examples and descriptions that explain how the instructions work, ‘The material here supplements the information in the preceding chapters; therefore, to get the most from this reference, you may also want to consult the Subject Index ro locate more details about specific instructions. Read the next sections for hints on using this chapter and for the meanings of various terms. Protected-Mode Instructions Protected-mode 80286, 80386, 80486, and Pentium instructions are not included in this reference. These instructions are typically used only for writing operating system code that ‘needs o juggle multiple processes apparently running at che same time but infact executing in sequence. The prorected-mode programming’s main purpose is to switch among such processes rapidly enough to give th illusion of simultaneous execution. ‘Some people may criticize the omission of proected-mode instructions in this reference but, after much thought aboue the subject, I decided that to list che instructions without also including the necessary background material required co write multitasking operating sys- tem software would be nothing more than a waste of space. For application programming, protected-mode instructions are not needed. Even so, this book would be incomplete if it did not atleast mention the protected-mode instruction set (See Table 16.1.) Fora list of books that contain more information about using these instructions and about writing multitasking operating systems, se the Bibliography. ro Special 80286, 80386, 80486, and Pentium non-protected-mode instructions such as bound, ‘entet Leave, and the conditional set instructions are covered here in detail along with syntax Rereesce bound Processor: 8086/88 Purpose ‘Syntax/Example Sample Code See Also bsf Check Array Index Against Bounds 80286 80386/486 Flags: of df if uf sf af af pf of a Verifies chat an array index is within a specified range. bound regW, memDW bound si, {word bx) 80386/486 only bound regDW, memQW bound esi, (qword x} oarases LowBound ow 100 highBound OW 199 coveses 286, nov si, 105 bound $i, {Lowsound) Load si with index valve check sf index is in bounds ‘Assign the index value to the frst operand and the addres ofthe index range values to the second operand. This structure must contain two words (or, optionally, wo doublewords on the £80386/486) with the lower value first (ac the lower address). If the value of the first operand is not within the numeric range of these ewo values, a type 5 interrupt is shared by the Prine Screen function; therefore, you must trap and prevent Print Screen ‘operations before using bound Bit Scan Forward Processor: 8086/88 Purpose Syntax/Example Sample Code Description 80286 80386/486 Flags: of dF if tf sf af af pf cf a a Scans bits in LSD to MSD order. bsf regW, regWl memW sf ex, ox baf regDW, regDW memDW af ect, (dword var} 386 mov dx, @860n dst ox, oe sz short e@10 + Skip shift if all bits she ox, ch nat dx by ch (Gx = @ eot0: ‘The firse operand to ost holds the result of scanning the second ‘operand from right to left (starting at bic 0). [Fall bits are 0, then 2 is set to 1, and the frst operand is unchanged. Ifa 1 bic is located, then 2f is set to 0, and che first operand is set to the bie ‘Assay Lancuace Rewence Guioe number. The sample uses this value to shift a bit in & into the LSD position. SeeAlio —oan bsr can Reverse Processor: 8086/88 80286 80386/486 Flags: of df if f sf 2f af pf of in ofbregees Purpore Seana bis in MSD vo LSD ovder Syntax/Ecample barrel, regW\ memW bar ox, nord be) Bae regDW, regDWI memDW ber ocx, eo Sample Code 388 ov dx, e@seh {Set Dit murber 6 to 1 sr ex, {Sean (ex = 0006h) jz short e818 1 Skip shift if all bits = @ she dx, el } smite dx by el (ax = 000th) coro: Description The frst operand to bsr holds the result of scanning the second coperand from left to right (starting at the MSD). IF all bits are 0, then 2f is set to 1, and the first operand is unchanged. IF 1 bit is located, then 2f is set o 0, and the first operand is set to the bit number. The sample uses this value to shift = the LSD position. See Also bot bswap byte Sap Processor: 8086/88 80286 80386 80486 Flags: of df if cf sf of af pf cf ry Purpose ‘Swaps bytes in a 32-bie register to convert values between lttle- and big-endian formats Syntas/Example swap regDW bewap eax Sample Code 406 nov eax, QABCDIZS4n ; Assign test value to eax bewap_ eax Snap bytes (eax * 94126088) evap eax } Swap oytes (eax = AB001204) Description Use this instruction on 80486 and later-model processors 0 convert data between litde-and big-endian forms. Intel proces- sors store data in litte-endian form (least significant values at lower addresses). Motorola processors store data in big-endian form (least significant values at higher addresses). You can use swap to convert data files for computer systems based on these processors such as PCs and Macintoshes. 16 715 i fy (Ciao ime 716 bt Processor: 8086/88 Purpose Syntax/Example Sample Code Description See Also btc Processor: 8086/88 ‘As the Sample Code demonstrates, the instruction operates 38 @ togele. You can use bswap to convert data without having to determine the data’ current format. Be sure co specify a 32-bic register for this instruction. IF you specify a 16-bit register, the results are undefined, xorg Bit Test 80286 803861486 Flags: of df if of of af af pf of a -------- a Copies abit co the cary flag be regit| memW, imB be ax, 14 be reg memW, reg W” Dt word var}, ox be regDW memDW, immB ot eax, 6 be regDWI memDW, regDW vt tdword vert, cox mov ax, @260h + Assign a test value to dx bt ox, 9 } Gopy bit number 9 to of ic opto | Test of call procedure } Gall procedure sf bit 9= 0 oy ‘The first operand to b¢ must be a word or doubleword register ‘or memory reference. The second operand may be a word (0-15) or doubleword (0-31) register or immediate value. Executing b copies the bit from the first operand ac the position specified by the second operand to ef. You can then use je oF Jne co test whether this bie was 1 or 0. bte, ber, pts, test Test and Complement 80286 80386486 Flags: of df if uf sf af af ph of a --------a4 Copies a bic to the carry flag and then complements the bit in Purpose Syntax/Example the original value bee regWI mem\W, immB —bte ax, 14 bre rg| memlV. regi? bee (ward var], ox bee regDWI memDW, immB bre eax, 8 buc regDWI memDW, regDW bee (dword vari, ecx : i¢ AsomrlwancRewoc coe] & EF Sample Code °386, ‘ov dx, 0200); Assign a test value to dx bee dx, ©} Copy BLt number 9 to cf and complement je 0010 } Test of cal procedure; Call procedure sf bit 9 = 0 Description ‘The operands and actions of te ate identical ro bt, but afer copying the specified bit to ef, chat bit is complemented ‘oggled) in the original value. In the sample, this leaves dx equal 10.0. Despite this, che zero flag is not set See Also bt, btr, bts, test btr est and Reset Processor: 8086/88 80286 80386/486 Flags: of df if of sf af af pf of a ~-------s Purpose Copies bit to the carry lag and then resets the bit in the original value. Syntas/Example bs regW\ memW, immB ber word vari, 5 ber regi mem W, regi” ber dx, ox ber regDW! memDW, immB —btr (dword var}, 6 bur regDW memDW, regDW dtr edx, ec Sample Code P26 ov ox, ascoh + Assign test value to dx fov ex, 15 {assign bit number to cx ber ox, ox j Copy bit to cf and reset “The operands and actions of tr are identical co bt, but afer copying the specified bit to ef, thac bit is reset to O in the ‘original value, In che sample, this changes dx 10 02BCDh, See Also bt, bte, bts, test bts Bit Test and Set Processor: 8086/88 80286 80386/486 Flags: of df if of sf af af pf of a ~ = ------ a Purpos Copies abit o the cary flag and then sets the bic inthe original value. Symtas/Example rs egW\ memW, immB bes ox, 4 bes eg mem Wag bts (word var}, ox bis regDW! memDW, immB bts eax, 8 bis regDW memDW, regDW ots owed varl, 96x 717 718 [ar Sample Code Description See Alzo call Processor 8086/88 Purpose Syntax/Example Sample Code Description See Also Rereance P9086 mov dx, @AscOn —; Assign test value to dx nov ex, 14 ; Assign bit munber to ex bts dx, ox + Gopy bit to ef and set ‘The operands and actions of ts are identical to bt, but after copying the specified bit to ef, that bit i set to 1 in the original value. In che sample, this changes 6x to OEBCDh. bt, ote, btn, test Call Procedure 80286 803861486 Flagsof OF fF of sf of af pf of a a Calls a subroutine proceduce. call nearTarget call Here call farTarget call far ptr There all eg call &x call memW. call [word bx] call memDW. call (aroré bx} 803861486 only call reg DW call eax call mem EW. call [fword si} call Tines2 5 Cali subroutine inp Exit, Exit progcan PROG Ties + Subroutine aad ax, ax ‘Ada doubleword in aac dx, ox ax:dx to itself ret | Return fron subroutine NOP ‘The e212 instruction pushes the address of the next instruction ‘onto the stack and then jumps to the targe location, causing the insuctions in he subroutine proce oben executing Usually, a ret instruction ends the subroutine, popping the etna om hack ard conning he ogin with the instruction that follows the original cali, In most programs, the target will be a label, marking the fs instruction ofthe Subroutine. But the target may also be a memory reference ora 16-bit register that holds the address of the subroutine. The sample cals a small subroutine Times2, which adds the value in ax:6x to itself: The ret instruction causes the program to continue from jnp Exit. cbw Convert yet Word Procanor BOGGS BO2S6 SOSEGNG Fagraf Ut WW af af af pf @ Use dee to decrease a byte, word, oF doubleword (80386 only) register or memory value by 1. This is similar to subtracting 1 from unsigned values with sub, but faster. The sample demonstrates one ‘way to construct a loop, calling AnyProc (not shown) 100 times and continuing past jnz only after dee Finally decrements cx to 0. Unsigned Divi 80286 80386/486 Flags: of of if of sf of af ph ef a ry u---uuuun Divides two unsigned values. div regB | memB_ sv a iv reg | memW iv (word var} 80386/486 only div regDW | memDW > div {00rd bx} aTases var da OtFFFEN ; 191070 decimal coveses mov ax, {Word var]; Load tow word into ax mov dx, (word var + 2] } Load high word into dx mov bx, 1024 } Load divisor into bx iv bx {ax < 131070 / 1026 (ax = 127) Use div co divide unsigned integer values. The operand refers to the divisor. The dividend registers are determined by the divisor sine. Byte divisors are divided into ax, placing the quotient in a2 and the remainder in an. Word divisors ae divided into ax:ax (low-order word in a), placing the quotient in ax and the remainder in dx. Doubleword divisors (80386 only) are divided into edx:eax (low-order doubleword in eax), placing the quo- tient in eax and the remainder in esx If the result ofthe division is greater than the maximum value the designated quotient register can hold—or ifthe divisor equals 0—then a type 0 interrupt is generated. Unless steps are taken to tap this interrupt, DOS will hal the program and display a divide error message. This is Further complicated by the fact chat, for 8086/88 processors, the interrupt return address is arti] 1 6 for the instruction following siv, but, for 80286 and 80386 processors, the interrupt return address points to the div that caused the fault. See Also isiv enter Enter Procedure Processor: 8086/88 80286 80386/486 Flags: of df if tf sf 2f af pf cf a a ~~ 7 Purpose Creates a stack frame for a procedue’s local variables. Syntas/Example ener immW,0 enter 2,8 enter immVW,1 enter 8,1 enter immW, immB. enter 0,3 Sample Code P#00 AnyProc enter 6 + Reserve @ bytes for Local variables 5 Proved eave } Reclain reserved stack space ret } Return to caller ENOP AayProc Description Mostly used by high-level languages, enter prepares op and Subats fiom sp the numberof bytes specified by the Firs ‘operand, reserving space for variables on the stack, which can then be addressed by #8:pp. The second operand equals the nesting level and can be either an immediate 0 or 1 for fastest operation or a higher immediate value. The level is used by languages such as Pascal that allow true procedure nesting, providing a method for inner procedures to access loca variables declared on outer levels. The sample shows how to use enter to reserve 8 bytes of stack space for variables. To recover this space, execute Leave just before ret See Also eave, ret esc Escape Processor: 8086/88 80286 80386/486 Flags: of df if if sf of af pf cf a nN a ---- = Purpose Passes instructions to a coprocessor. Syntax/Example esc imm6, regB | regW esc 5, 0x ‘ese imm6, memAll” esc 8, [var] Sample Code #19 t(0) } Push operana wast } Wait required tor ec 8, ax 5 087 727 16 Ge 728 Description See Aleo hit Processor: 8086/88 You can use ese o pass instructions to a coprocessor. The fist ‘operand represents the instruction’ operation code. The second ‘operand specifies a destination or source value for the coprocessor instruction. Because Turbo Assembler recognizes math coprocessor instruction mnemonics, es¢ is rarely of much practical use. Ifyou do use eso, be aware that the 8087 requires a wait instruction before every math coprocessor instruction. ‘Turbo Assembler automaticaly inserts waits as needed— another reason to use coprocessor mnemonics instead of ese Halt 80286 80386/486 Flags: of df if uf sf of af pf cf a a --- Purpose Syntax/Example Sample Code Description Halk until interr Ile mo operands — nit elt + Disable maskable interrupts nis Pause until Mit or reset sti Enable maskable Snterrupts Execute nit to pause until the next interrupt signal is acknowl- edged or until a reset signal i received. If maskable interrupts are disabled, nit pauses the program until a reser signal or until a rnonmaskable interrupt is acknowledged. cui, sti Signed Integer Divide Processor: 8086/88 a Purpose Syntax/Example Sample Code 80286 80386/486 Flags: of df if ef sf af af pf cf nN us --uuuug iv regB | memB saiv at idiv regW | memW stv (word vari 80386/486 only idiv regDW | memDW — s0iv (aword x1 ov ax, 108 + Assign dividend to ax ov bi, -3 Assign divisor to bL iaiv bt § al < ax / bl (remainder in ah) neg at } Fin absolute value of al — enum P & Description See Also imul Processor: 8086/88 a Purpose Syntax/Bxample Use sdiv to divide signed integer values. The operand refers to the divisor. The dividend registers are determined by the divisor size. Byte divisors are divided into ax, placing the quotient in al and the remainder in ah. Word divisors are divided into ax:ax (low-order word in ax), placing the quotient in ax and the remainder in ax. Doubleword divisors (80386/486 only) are divided into ed: eax (low-order doubleword in eax), placing the quotient in eax and the remainder in eds. The remainder always has the same sign as the original dividend. “The sample divides 100 decimal by -3, placing the quotient ina1 (ODFh) and che remainder in ah (01), Remember that negative valucs like ODFh are expressed in ewo's complement form. To find the absolute value [3 in this case) use neg asin the sample. If the result ofthe division is grater than the maximum value the designed quotient register can hold—or if the divisor equals 0— then a ype 0 interrupr is generated, Unless steps are taken to trap thisiteupr, DOS wll hae he program and dp a de ror ‘message. This is further complicated by the fac that, for 8086/88, proctor ths ntrupt eta ades pin oh struction llowing div, but for 80286 and 80386/486 processors, che interrupt reurn address points o the div that caused the fault. av Signed integer Multiply 80286 80386486 Flags: of df if uf sf af af ph cf a a a---vusa ‘Muleiples ewo signed values. mul regB | memB nul [byte bx] imal reg | memW ind ox 80286, 80386/486 only irml regW, nom smut cx, 9 imal regW, im fmol bx, 451 iimul reglW, reg | memW, immB imu ox, [word bx], 3 il regW, regW | memW, immW imu ax, bx, 900 80386/486 only imal regDW | memDW smut (nord Dx imul regDW, immB smut eox, 18 imal regDW, immDW mul eax, 32769 imal regW, regW | memW aul bx, ox itmul regDW, regDW \ memDW nul eck, (drord\bx] irmul regDW, regDW | memDW, immB isul eax, eo, 12 imal rgDW, regDW | memDW, immDW smut’ eax, {dvord bx}, 95790 729 730 be [Par Revace Sample Code Description See Also in Processor: 8086/88 Purpose a ov al, 4 ov 01, 5 Multipticana Multiplier sul bi pax al * bt 5 (ax = OFFFBH, ef = o nov al, 127 } Multipticana roy bl, ~128 multiplier sul bi ax alt bb } (9x = aco8en, ef = of = Depending on the processor, smut has three basic formats, aking from one to three operands. Some forms require explicit regis- ters. The simplest form multiplies a byte register or variable by a, placing the result in ax. A similar form multiplies 2 word. register of variable by ax, placing the result in &x:ax (low-order word in ax). On the 80386/486 only, smut can multiply eax by a doubleword register or variable, placing the result in edx:eax. ‘With all these forms, ifboth of and of equal 0 after smul, then the high-order portion of the result is merely the sign extension of the low-order portion. In other words, as the fist part of che sample shows, multiplying 4 * -2 sets ax to OFFF8h. Because ct and of are 0, an (OFFh) extends the sign of the 8-bit answer in at (OFBh), creating a full 16-bit value, When cf and of are both set ‘oI, as in the second part of the sample, then the result occupies the full width of the destination register—in this case ax, which equals the two's complement value 0CO8Oh, or -16,256 in decimal, the product of 127 * -128. £80286 and 80386/486 processors expand on these basic forms with rmuliple-operand inut instructions. In the two-operand format, the frst operand is che multiplicands che second operand is the immediate byte or word multiplier. The product replaces the specified multiplicand register. In the three-operand format, Cpe ise operand species a destination regate forthe product, the sccond register holds the multiplicand, and the third operand is the immediate byte or word multiplier. The 80386/486 further «expands these forms, allowing various combinations of double- ‘word registers, memory references, and immediate values. With all these fet and of are O after imul, then the product ‘exactly fits within the specified destination register (always the fist ‘operand; otherwise, the produce is too large for this register. mul Input From Port 80286 80386/486 Flags: of df if cf sf af af pf cf a a - -------- Inputs values from ports. Syntas/Example Sample Code ‘seen anata Gvot_] in al, immB in al, 149 in ab, de in al, ox in ax, immB in ax, 01Fh in ax, de An ax, ox 80386 only: in eax, immB in eax, oFh in eax, de sn eax, oe otrte2se EO) 021n ; 8250 masks port An al, ctri2s9 and al, EnabletRa out ctrie2s8, al 5} Read 8259 enable masks Clear masked Dit |} Write new 6259 masks Description The in instruction reads the value of a hardware port into al, ax or eax (80386/486 only). As the sample shows, in is often used in conjunction with out and logical instructions such as and and, or to examine and change bit switches at various port addresses in the computer. The simplest form of in reads a byte value into a1 from an immediate port address in the range 0-255. To access higher port addresses, specify the addres in the ox register. See Alzo Ans, out inc Increment Processor: 8086/88 80286 80386/486 Flags: of df if of sf af af pf of a’ a aA --- aaa Purpose ‘Adds 1 coa register or variable. Syntas/Example inc regB | memB snc (byte bx} ine regW | memW ane ox 80386/486 only ine regDW | memDW > inc ecx Sample Code nov ex, ® 5 Initialize dx <0 aio. call. AnyProc } Call @ procedure ne ox bak att cap ox, 10 + Does dx = 10 jne e610 dump it dx <> 10 Description _ Use inc to increase a byte, word, or doubleword (80386/486 only) register ot memory value by 1. This is similar to adding to unsigned values with ada, but faster. The sample uses snc to construct a simple loop, using dx asa control value to calla procedure anyProe (not shown) 1000 times. (There may be more efficient ways to construct such a loop.) See Also dec 73 a ins insb insd insw Inpat rom Pot To Sing Processor: 8086/88 80286 80386/486 Flags: of df if wf sf of af pf of ne geeeeeses Purpose Taps valu fom pora wa quence of ys, word or doublewords in memory. Symts/Example igh di men de cop ins tear), ox ins di | memW, de rep ins (word var], ox insb mo operands rep insb insw no operands rep insw 803861685 only ins regDW | miemDW, de cop ins {dword var}, ox insd mo operands rep ins Sample Code NOTE: Oon't cun this sample! mov ox, 108 Nunber of words to read mov 3x, 48h Specity port address mov oi, offset st { Address destination aie } Auto-snerenent i ep insw } Load steing from port Description As with all string instructions, the register assignments for ins and its shorthand forms insb, insd (80386/486 only), and insw are fixed, even if you specify address labels explicitly. The destination resister is always es:6t, and the segment cannot be ‘overridden, The port number must be placed in ax. (Don't forget to do this also for the shorthand mnemonics!) IFaf = 0, then ins increments dis iff = 1, ins decrements ai. Normally, you'l preface ans with rep, repeating the instruction for the ‘numberof times specified in ex as illustrated inthe sample. See Also ‘caps, cmpsd, cmos, ods, Lodsb, 1odsd, 1odsw, novs, novsb, Iovsd, novsH, outs, OUESb, oUtsd, outsK, scas, scasb, scasd, seasm, stos, stosb, stosd, stosw int. Call Interrupt Service Routine Processor: 8086/88 80286 80386/486 Flags: of df if uf sf of af pf of rn a a - -00----- Purpose Calls interrupe service routine by number. Syntax/Example int 3 int 3 in immB nt 200 732 Sample Code Description See Also into Processor: 8086/88 a eater] 16 arases fiessage db “Mastering Turbo Assembler’, 'S' coneseG nov dx, offset message; Address message string tov ah, 8 + Specify 008 function number nt 20h Gail 008 function handler ‘Although there are wo forms of int, they appear the same in programs. The first form is a special 1-byte code (OCCh) that debuggers typically use to replace instructions at specified breakpoints. You can insert this code yourself to cause most debuggers (Turbo Debugger included) to halt at various loca- tions. The second form specifies a byte value asthe interrupt ‘number, which can range from 0 to 255, representing one of 256 four-byte vector pointer addresses stored in memory beginning at address 00000000. Executing int runs the inter- rupt service routine at the vectored address for this interrupt number. Just before this, the processor pushes onto the stack the flags and the return address, which are restored in the interrupt service routine by executing iret. In addition, the interrupt and trap flags are set ro 0. (These two flags are restored by iret, and, because the flags are changed only forthe incerrupe service routine, some 8086 references incorrectly indicate that st and tt ate not changed by int.) soto, tret Interrupt On Overflow 80286 80386/486 Flags: of df if tf sf of af pf ef 4 a --aa- Purpose Syntax/Example Sample Code Description See Also Generates a type 4 interrupt if of into mo operands into P86 mul ex, [dword bx] 5 eex <- eex * [bx] into { Interrupt on overtiow By installing an interrupt service routine for interrupt 4, you can tue tnt to ore execution of this ode ifthe overflow agi st by a previous operation. The inscruction into behaves like ant, pushing the flags and recurn address onto the stack, resetting ** and if, and jumping ro the vector for interrupt 4. The interrupt code can then deal with the error and execute iret to resume program execution. The sample demonstrates how you might tse into to detect an overflow from an imut instruction for an 80386 processor. int, Aret 733 734 Roster invd Invalidate Cache Processor: 8086/88 80286 80386 80486 Flags: of df if ef sf of af pf cf a Purpose Flushes the 80486 internal instruction cache, and also issues a special bus cycle that hardware designers can use as a command to flush any caches that are external to the processor. Syntax/Example ind no operands snvd Sample Code 496 anv 1 Flush cache and issue flush bus cycle Description Use this instruction only on 80486 processors. It requires no ‘operands and i affects no flags. Intel states that snvd is “imple mentation dependent,” meaning that future processors may implement the instruction differently. There ar few if any good reasons for application-level programs to use tis instruction. See Also Anvipo, wosava invl ps Invalidate TLB Entry Processor: 8086/88 80286 80386 80486 Flags: of df if of af of af pf of a eee Purpose Invalidates an enuy in che TLB, otherwise known as the “trans- lation lookaside butfer.”, Syntas/Example invipg, renal! invipg table Sample Cade (none: see Description) Description This instruction is valid only for 80486 processors, and Intel states that it may or may not be provided on furure CPUs. The instruction is used to invalidate entries in the TLB, which translates linear and physical addresses. It should not be used in application programming. See Also snve, wosnve iret iretd Inept Return Processor: 8086/88 80286 80386/486 Flags: of df if uf sf af af pf cf a4 4 wewwewwe Purpose Returns from an incerrupe service routine. Syntax/Example icet no operands iret 803861486 only inetd no operant ireta Sample Code Description See Also ___________ § aman) A PROC MyISA push ax ; Save any changed registers sth | Enable maskable interrupts 1 Procedure code iret 5 Return from interrupt NDP Execute iret as the last instruction in an interrupt service routine (ISR). The instruction pops the return address 28:59 from the stack and the flags, continuing the program from the poine of the interruption. Use the same iret whether the interrupt was generated externally or internally by a fault condition such as an illegal division or by the int and into instructions. On 80386/486-based systems only, iretd can be used to return to 2 32-bit segment, popping the full-width ip txtended istration plntet Rom the tack Ant, into j-condition Jump Condtionally Processor: 8086/88 rn Purpose Syntax/Example Sample Code Description See Also 80286 80386/486 Flags of df if of sf of af pf cf a a —----- —— Jumps to a new location if certain lags are set and/or reset. condition short Target jge 890 comp ax, 1024 +} Compare ax and 1028 jp 0620 i sump if ax « 1028 All conditional jumps operate similarly and, therefore, ae listed roger het fo egy eetence, Also, athough some of the ‘mnemonics represent the same instructions (for example, je and 42) the mnemonics are listed separately. As Table 16.4 shows, certain flag settings control whether the jump is made. The target address of a conditional jump is signed displacement of “138 co +127 bytes away from the address ofthe following instruction, On 80386 systems only, displacements may range from ~32,768 to «32,767 bytes. ‘The sample demonstrates how to use a conditional jump after a cep to test the value ofa register. Comparing ax with 1,024 and. following with sb jumps to the target address ifthe value of ax is dedow 1.834, Conditions that we the words “above” and “below” refer co unsigned comparisons; conditions that use the words “greater” and "less refer to signed comparisons. imo 735 736 [Pa = Rare Table 16.4, Conditional jump Reference. Instruction jna jnte jnb jnbe ine ine ing jnge jal jnle jna inp jos jnz Sump if. above above or equal below below or equal any ex equals 0 ecx equals 0 equal greater ‘greater or equal less lessor equal overflow patiy parity even parity odd sign not above not above or equal not below not below or qual not carry not equal or greater not grater or equal not less not less or equal not overflow not parity not sign Flags (cf = 0) & (2 = 0) (f=0) (f= 1) (f= 1) | Gf 1) (f=1) ~ (80386/486 only) (ef=1) (sf = of & (2f = 0) (f= 0 (Fes of) (sf <> of) | (@F=1) (of=1) (f=) f=) (f=1) | @f=1) (f= 1) (f=0) (cf = 0) & (f= 0) (f=0) (f= 0) (sf of) | G@f=1) Processor: 8086/88 a Feannvinener tana Gan] Jump Uncond 80286 803861486 Flags: of df if of sf af af pf cf a a ~-------- ally Purpose Syntax/Example Sample Code Description See Also lahf Processor: 8086/88 Jumps to a new location jmp shortTarget mp short 0010 mp nearTarget jap Closeby imp farTarges jmp far Overthere jmp reg P memW jap bx jmp memDW np (word bx} £80386/486 only jmp regDW sap ecx or bx, Bx 3 Does bx = 07 Jnz continue j dup if bx <0 Jno &xt j Else jump to exit Continue: ‘The jap instruction causes program execution to continuc at the Adres spectied asa displacement from the instruction folowing the jnp. In assembly language programs, Turbo Assembler calculates the displacement from a label that you specify asthe ‘operand, automatically using the most efficient form of the instruction possible. ‘There's rarely any good reason to calculate displacements manually. ‘When jumping to higher addresses, use the SH08T operator asin jmp SHORT Nearby, of Turbo Assembler will insere wasteful nop instructions to allow for che possiblity thatthe addeess lace will prove to be farther than about 128 bytes away. In place of an explicc label, you can specify the target address in a register or via a memory eference. The 80386/486 allows extended registers co hold 32-bit offset addresses. This powerful ability is especialy useful in creating “jump tables,” which contain lists of locations to which control passes based on certain conditions. S-condition Load Fags Into a Register fame sree 80286 80386/486 Flags:of df if tf sf af af pf cf Nn rn ------ a Purpose Copies sf, 2f, saf, and ef to ah Syntax/Example \ahf no operands dant Sample Code abt 5 Load fags in to an test ah, @0n jnz 0010 j Test sf, 2f, of Jump sf” any’ Flag = 737 16 =e Description Execute 1ahf to load the five flags (7), 24(6), af (4), pf(2), and cf (9) into lower 4 bits of register ah. Bit numbers are shown in parentheses, After executing lant, other bits in an are unde- fined and may also change. See Also sant Ids Load Pointer and ds Processor: 8086/88 80286 80386/486 Flags: of df if ff sf 2f af pf cf aa a ~-------- Purpose Loads pointer fiom memory into a register and os. Syntasi/Example Ids regW, memDW ds si, [bp + 4 80386/486 only Ids regDW, memFW Ads edi, [bx] Sample Code push cs } Push segnent mov ax, offset var Load offeet push ax | Push offset push bp + Save bo mov bp, $0 | Address stack with bp ds si, (bp + 2) j Load pounter to os:2i, Description Use 14s to load both a 16-bit general-purpose register (usually +) and the as segment register with a 32-bit pointer stored in memory. The memDW operand may be any of the usual addressing modes, except fora direc addeess, which is not permitted. The 80386/486 can load a 48-bie pointer into an extended 32-bit register plus ds. The sample demonstrates how ‘0 pick up a pointer, peshaps passed toa subroutine by address oon the stack. The fist part of the sample pushes the segment es and offiet values ofa variable (nor shown) onto the stack the second part uses 168 along with tp to load as:6s with the pointer value. See Also lea, les, 1fs, 19s, 155. lea Load Efective Address Processor: 8086/88 80286 80386/486 Flags: of df if tf sf 2f af pf cf aa a ~ ee Purpose Loads offset address of memory reference into a register. Syntax/Example lea reg, menW tea bx, (bp + 21 803861486 only 738 lea reg | regDW, memW | memDW 19a edi, {dword bp + 2) Sample Code Description See Also leave Processor: 8086/88 DATASEG array db 8¢ cup (0) ‘coveses lea bx, (array + si]; Use this roy bx, offset array}. -instead of these ada bx, sh } two Lines tea bt, [array + bp + si] 5 Use this. nov bx, offset arcay —j-s-Anstead of ‘these acd bx, DD. j three Lines: ado bx, si Use 1ea to load the offset addres, also called the effective address, into a word register or a doubleword register on 80386! 486 systems. When you need to use a complex memory refer~ ence repeatedly —or when you need ro load a register, usually bx, with the address ofa table element perhaps for use with the xiat jnstruction—you can use 1ea to compute the offset address. The ‘ample demonstrates how doing this can perform the work of two or three instructions. The frst code line performs the same taskeas lines cwo and hee; che fourth code line does the same job as the last chree lines. ds, 1es, 1fs, 19s, ss Leave Procedure 80286 80386/486 Flags: of df if tf sf af af pf of a a ~ —------- a Purpose Syntax/Example Sample Code Description See Also Removes from the stack local variable space allocated by enter. leave no operands eave PROG AnyProc enter 6,0 j Reserve 6 bytes for local variables ; Reclsin reserved stack space ret # Return to caller ENDP AnyProe Just before a ret instruction, use Leave to reclaim stack space previously allocated by enter atthe star ofa procedure. Usually, high-level language compilers use 1eave and enter co implement functions and procedures, but you can certainly use these instructions in pure assembly language programs, 100. A leave performs the two steps nov sp, 9p and pop bp, thus restoring the Stack pointer and to, which was pushed onto the stack by enter, Tear ree] f 739 16 ee | 740 es Load Pointer and es Processor: 8086/88 rn Purpose Syntas/Example Sample Code Description See Aleo 80286 80386/486 Flags: of dF if uf sf af af pf of a a Loads pointer from memory into a register and es. les reg, memDW. es di, [bp + 4) 803861486 only les regDW, memFW 0s esi, (bx! push ds 5 Push segnent ov ax, offset var + Load offset push ax | Push offset push bp 1 Save bp ov bp, sp | Address stack witn Bp es oi, [bp + 2) } Load pointer to es:ai Use 1es to load both a 16-bit general-purpose register (usually 11) and the es segment register with a 32-bit pointer stored in memory. The memDW operand may be any of the usual addressing modes, except for a direct address, which is not permitted. The 80386/486 can load a 48-bit pointer inco an extended 32-bit register plus es. The sample demonstrates how to set ¢s:di to point to a variable, perhaps passed to a subroutine by address on the stack. The first part of che sample pushes the segment ds and offset values of var (not shown) onto the stack; the second part uses 1es along with bp co load es:4i with the pointer value Ads, 1ea, Ifs, Igs, 18s Ifs Igs Load Pointer and fs, gs Processor: 8086/88 Purpose Syntax/Example Sample Code 80286 80386/486 Flags: of df if of sf 2f af pf cf 2 - Loads pointer from memory into a register and #8 (1¢8) oF into 98 (19s), fs regW, memDW. fo dt, bp + 41 fs regDW, memFW 148 esi, 10x) Igs regW, memDW gs di, {bp + 4) Igs regDW, memFW igs esi, {bx} push os {Push segeent pusn 0 5 Push high offset Description See Also lock ‘soa ova Ree] push bo _ ave» Use 11s and 19s to load a 16- oF 32-bit offset pointer plus a 16-bit segment address value into any 16- or 32-bie register and cither the fs or gs segment registers, available only on 80386/ 4486 systems, Except for the ability to load 48-bit pointers, these two instructions are similar o 26s and Les and are sypically used in procedures to access variables passed to subroutines by address con the stack, Ads, 1ea, 1e8, 195 Lock the Bus HOCK eee Processor: 8086/88 80286 80386/486 Flags: of df if of sf af af pf cf a a ----- - a Purpose ‘Asserts bus lock signal for next instruction. Syntax/Esample lock no operands Lock xong [senaphorel, al Sample Code Description See Also Note: Don't run this! ‘nov 61, t } Set al tot Lock xchg (semapnore], d) 5 Exchange dl & mesory ; Does 1 = 07 j dump until 62 © 0 Use Lock asa prefix to instructions that reference memory shared by more chan one processor. (PCs have single processors, so lock is rarely used in PC programming.) Typically, tock prefaces xeng ‘on 8086/88 systems; novs, ins, and outs on 80286/386/486 systems: and ade, a6, and, bt, Otc, Dtr, bts, dec inc, neg, not, fr, sb, sub, and xor on 80386/486 systems when one operand is a memory reference. I's not necessary to preface xchg with lock oon 80286/386/486 systems, which do this automaticaly. “The hypothetical sample shows a typical use for 1ock—setting a flag called a semaphore co prepare for exclusive use ofa device of perhaps, other memory blocks. The lock on the xene prevents {wo processors from accessing the same byte; therefore, if 1 is 0, the program can safely proceed while the other processor, which is running a similar or even the same routine, will pause until che firse process again resets the semaphore to 0. xehg 74a reste 742 Load String lods lds lodsdlodsw Processor: 8086/88 a Purpose Syntax/Example Sample Code Description See Also 80286 80386/486 Flags: of df if f sf 2f af pf cf a a Loads strings of values into the accumulator. Jods fes)memB rods (byte source] leds (ocfmemW ods ward es:sil lodsb no operands oad lodsw no aperands —— Yodew 803861486 Ieee orien DW rods (ovord source) lodsd no operand ode ov ai, offset string; Adgress string mith 6¢:44 ov ox, MaxGount } Maxinim 100p8 10 0 aie | Autorincrenent si eee: Toes fale (asst) ot foune ine si } Si addresses Description These two mnemonics represent the same instruction and operate nearly identically to Loope and 1oope, except that the jump to a target address is made only if, after decrementing ex, this leaves ex <> @ and if 2¢ = 0, The sample uses Loopne to locate a period in a file-name string, starting the scan at the end. of the sting and jumping to Exit (not shown) if no period is found or incrementing si to the period character if found See Also 4200p, 109pe, 1oop2 Iss Load Ponte ands Processor: 8086/88 80286 80386/486 Flags: of df if of sf 2F af pf cf in fo to a Purpose Loads poner rom memory na veginerand ve Syntax/Example ss regW, memDW_ rss si, {op + 21 744 Ws ngDW momPW tas ool, tox Sample Code See Also mov nov [oldes), $8 + Save old stack segnent mov (oldsp], 6p ang olé stack pointer ss sp, [nenstack] Load ss:sp with new values fov sp, (0ldsp1 5 Restore sp (interrupts disabled) nov s8, [oldss] | Restore ss (On 80386/486 systems, use 188 to load a 16- or 32-bit offset pointer plus a 16-bie segment address value into any 16- or 32- bic register and the ss stack segment register, Normally, the offset value will be loaded into sp, but there's no restriction on, tusing 188 to load other registers. One way to use 188 is to pick up the address of an alternative stack as the sample demonstrates. Ids, 26a, 16s, Its Move Data Processor: 8086/88 80286 80386/486 Flags: of df if of sf of af pf of a4 a -------- Purpose “Moves values between repstrs or between registers and memory. Symas/Example mov al, memB nov al, {abytel mov ax, memW fov ax, (avera} mov memB, al fnov abytel, al mov meV ae tov (awore], & mov regi |'memB, regB | immB nov a, ch mov reg |_memW, regW | mm nov (aword), 1026 mov regB, memB nov dl, [abyte) mov regW, mem W nov ax, {avers} 80386/486 on! mov eax, memDW ov eax, {26word) mov memDW, eax ov {adword}, eax mov regDW | memDW, regDW | immDW mov edx, 99999 mov regDW, memDW fov ex, (adword) Sample Code oxTASEG var ab 10 dup (9) 1 A to-byte variable cooeses ov bx, @ 5 Initianize px to ov ex, 10 } Initialize cx to 10 coro. tov [byte var + bx1, ch + Copy et to menory ine bx } Incresent pointer oop e108 } Loop on ox Description ‘The nov instruction is probably the most heavily used of all instructions in 8086 programming. Various forms of roy allow transferring bytes, words, and doublewords (80386/486 only) 45 7 Tc 746 Reve See Also beeween registers or berween registers and memory, using all the usual memory-addressing modes. There are a few restrictions on nov that are not evident from the syntax list. The direction of nov is from right to left—eransfer- ring the value of the second operand to the first. The value of che second operand is never affected. When both operands are registers, only one of those operands may be a segment register; therefore, it’s legal to write mov es, ax and nov faword], os, but it’s notlegal ro write nov 6s, es. When one operand is 2 segment register, interrupts are disabled for the next instruction, allowing a nov to ss to be followed with a mov to sp, eliminating the danger that an interrupt signal will occur before the full sack pointer 88:89 is initialized. Another restriction is that both ‘operands may not be memory references—all moves to and from memory must pass through a register. (See novs for an insteuc- tion that can move values between two memory locations.) When one register operand is a1, ax, and eax (80386/486 only), ‘Turbo Assembler generates a faster form of aov. If the aceumula- tors free, you should use it in nov instructions to improve program performance. ‘The sample shows how nov is used to initialize registers, used here to store the successive values 10,9,.1 in a variable. Another nov copies the value of c1 to memory using base- addressing mode with bx. fovs, lods, stos movs movsb movsd movsw Move Sing Processor: 8086/88 80286 80386/486 Flags: of df if wf sf af af pf cf aa a es Purpose Moves strings of values directly berween two memory locations Syntax/Example movs memB, [esmemB nove [vars], [var] mows memW, [ex]memW nove [vars], (es:9i1 movsb no operands novsb -movsw no operands novsw 80386/486 only movs memDW, [e:JmemDW wavs {edi}, tes:vars) movsd no operands sovsd Sample Code nov ax, data } Initialize ds to address mov ds,ax + of data segnent mov es, ax Make es = os ASSUME es :0GROUP Tell tase where es points oy si, offset string ‘Adgress source string ov di, offset streopy j Address destination See Also movsx Processor: 8086/88 Purpose Asia Lancunce Revnence Gude ov ex, strlen + Assign count to cx jexe Exit Don't copy if ex = © cua } Auto-inorenent si, di rep movsb } Copy string to strcopy “The novs instruction, plus its shorthand forms novsb, novse (80386/486 only), and novew, moves one value in memory directly to another memory location. The fist operand must be o8:6i, addressing the destination for the move. The second operand must be e:si or with a segment override es:si, addressing the source for the move. The extended 32-bit registers edt and esi may be used in 80386/486 programs. Executing novs copies 1 byte from the source location to the destination. After this, fat = @, both si land 6; (or est and e¢3) are advanced by the number of bytes being moved. [fet = 1, the two registers are decremented by the number of bytes being moved. These register assignments are fixed —even, asin some of the examples, if you specify explicie labels, which ‘Turbo Assembler will check to ensure that the vatiables are in the appropriate segments. It's still your responsibility to load at and si with the offset addresses ofthe variables. The shorthand forms of rove require no operands. There are no operational differences berween the different mnemonics, Usually, novs is prefaced with a rep prefix, repeating the insteuc- tion for the number of times specified in ex. As the sample shows, this lets you create powerful instructions to move blocks of memory from one place to another—in this case, copying string to strcopy. AS a reminder, che instructions to initialize Segment registers are also shown in the sample. Effectively using ove (as well as other string instructions) requires careful planning and control of segment registers. Cempsb, enpsd, cmpsw, ins, insb, insd, nsw, 100s, lodsb, 1odsd, odsm, outs, outsb, outed, OUtSM, rep, $cas, scab, Seas, Scasy, stos, stosb, stos¢, stosw Move and Extend Sign 80286 80386/486 Flags of df if of sf af af pf cf a ~ -------- ‘Moves signed values from smaller registers and memory loca- tions into larger registers, extending the sign bit. movsx regW, regB | memB_— aovsx ox, a movsx regDW, regB | memB aovsx eax, (abyte] movsx regDW, regW | memW novsx etx, ox nov al, -1 pale dx = eo0c0n ovex dx, al idee 747 1 6 [Parl = Reroee _ 5 labyte) = -1 eax en 3 eax = OFFFFFFFEH ov ax, 1 ant nov edx edx 0 fovsx esx, ax 1 gx = OFFFFFFFEN Description On 80386/486 sysrems, use novsx to copy signed values with fewer smumbers of bits to larger registers. For example, you can use novsx to load a word register such as ax with a byte value from memory and have the processor automaticaly initialize an, extending the sign of the copied value as needed. The destination (frst operand) to novex must be a register. The source (second operand) may be 2 register or memory reference. The samples demonstrate how t0 use snovsx to transfer values beeween dissimilar registers. See Also ov, novs, novex movzx ‘Move and Extend Zero Sign Processor: 8086/88 80286 80386/486 Flags: of df if of sf af af pf cf ry - Purpose ‘Moves unsigned values from smaller registers and memory locations into larger resisters, zeroing the most significant digits. sax/Example movex regW, repB | memB novax dx, (abyte] ™ mmovax mgDW, regB I'memB_ rover vot, th movex regDW, régW | 'memW sovix ecx, (aword) Sample Code nov at,-1 ov ox, : movex dx, al ; ov fabyte], 1 5 mov eax, ~1 i movex eax, (abyte] i nov ax, 1 : nov edx, =1 A fmov2x eax, ax : 0090001" Description On 80386 systems, use novzx to copy unsigned values with fewer numbers of bits to larger regisers—similar to the way you can use snovsx. For example, wovzx can load an extended 32-bit register such as ecx with a word value from memory and have che processor automatically zero the upper 16-bits of eex. The destination (ese ‘operand) to movzx must be a register. The source (second operand) may bea register or memory reference. The samples demonstrate hhow to use novzx to transfer values berween dissimilar registers. See Also ov, aovs, novsx 748 — mul Lance Rernence Gut Unsigned Multiplication Processor: 8086/88 a Purpose Syntax/Example Sample Code Description. See Also 80286 80386486 Flags of df if of sf af af pf of a a a ouuua Multiplies wo unsigned values. mul regB | memB mul bt mul regW/1 memW mu awordd 803861486 only mul regDW | memDW mut eds araseS multiplicand dw 1028 multiplier dw 92 anewor vO cCovESEG ov ax, [multiplicand) ; Load multiplicand into ax ul (multiplier) } duiax <- ax * multiplier je Exit } dump if result > 16 bits rrov {answer}, ax } Else store answer Unsigned multiplication in 8086 programming is considerably similar than signed multiplication (see inu2). The single operand to nul must bea general-purpose register or a memory reference, representing the multiplier. The size of the multiplier determines the location ofthe mulilicand and product. If the multiplier a byte, then the multiplicand is #1, and che product is deposited in ax. Ifthe multiplic is a word, then the muliplicand is ax, and the result is placed in or:ax with ex holding the low-order portion of the resule. If che multiplier is a doubleword (80386/ 486 only), then the mulkiplicand isin eax, and the product appears in eoxzeax, with the low-order 32 bits in eax. Overflow of the destination registers is not possibe. ‘After aul, the of and of flags can be used to determine the size of the result. Both flags are set to 1 ifthe product cakes more bits than the specified source; otherwise, both flags are set co 0. ‘Thus, iff = @ after mut bl, then ah is 0, and the 8-bie result fits in at. fet = 1 after mut bx, then the result occupies the full 32- bit double register ax:ax. As the sample demonstrates, you can ‘optionally test of (or of) after muh to detect a result larger than the size ofthe original operands. im 749 750 erence, Processor: 8086/88 ny Purpose Syntax/Example Sample Code See Also no Processor: 8086/88 a Purpose Syntax/Example Sample Code ‘Two's Complement Negation 80286 80386/486 Flags: of df if tf sf xf af pf cf a a a aaaae [Negates (forms two's complement) ofa value, neg regB | memB_ neg {abyte} neg regW | memW neg ax 80386/486 only neg regDW | regDW neg eax Assign values to jax and dx ax < ax - dx (ax = OFFFEN) usp if ax >= 0 jae e010 neg ax Find absolute value (ax = @0e2) mov di, *~" j Display a minus sign mov ah, 2 j via DOS function 2 int 2th Gal 005: care: } Continue here ‘Apply neg to form the ewo's complement of a register or memor alte, When he original values negative number in two complement form, neg finds the absolute positive equivalent of the value Tentrcon open by ebsracing the ogi a, fiom 0, an operation that is logically equivalent to its ihihevauc bon Oo fan fom 10 and ten ing AS the sample demonstrates, if the result ofa subtraction is negative, a ‘minus sign can be sent to the standard DOS output file, and the result in ax can be negated. Nor shown isthe code after 6010: that would then write the absolue value of ax tothe standard output, ‘thus displaying the fll negative number in decimal not No Operation 80286 80386/486 Flags: of df if of sf of af pf cf a a ~ -------- ‘Occupies 1 byte of machine code but has no operational effect. nop no operands nop jmp 0020 } dump to forward Lapel nop 3 Inserted by Turbo Assembler... ez } eoff this label is within about 3128 bytes mariner) Op Description Turbo Assembler inserts nop instructions to reserve bytes in cases where the exact size ofan instruction is determined by code later in the program. For example, a jmp to a forward label is assumed to be 3 bytes long. Buc if the jmp destination proves to be within about 128 bytes, the assembler changes the jnp to a more efficient 2-byte form, leaving the unneeded third byte equal toa nop. (You can avo tation by prccing the arg ades of forward ab with the SHORT operator.) Another use for nop is during debugging Ifyou want to remove an instruction, instead of quitting the debugger, loading your editor, making a modification, and reassembling, just poke a few nop bytes (90h) over the instruction. ‘You can then run the program and examine the effects without this instruction in place—a useful debugging technique, Some refer- ‘ences recommend using nop to adjust the timing of sofware loops, athough bese its amos moss wo pei the ct mings ‘of multiple instructions in 8086 programming—especally in an Intemupediven computer system™—ths us of rp fs dubious ‘The nop insteuctior to the instructions xeng ax, ax and xchg eax, eax (80386/486 only), both of which assemble to the same machine code as nop. See Abo ha not Ones Complement Negation Processor: 8086/88 80286 80386/486 Flags: of df if tf sf af af pf cf a eaeree ve Purpose Toggles all 1 bits to O and all 0 bits to 1 in a value. Syntax/Example not regB | memB ot dn not reg memW not ax £80386/486 only not regDW | memDW not (eword var] Sample Code osTASEG false Ea @ ; Value representing false ‘true EQU ~1 + Value representing true flag db true } Initialize flag to true covEsES comp [flag], false; 18 the flag false? ye ee10 ump if flag = false call Subroutine =; Else call a subroutine eei0: ‘not {flag} { Toggle flag value Description Use not co toggle al | bits ina value to 0 and all 0 bits to “This is often useful for toggling the value of a true and false flag, asin the sample. (The referenced subroutine is not shown.) See Also neg 751 752 Paws we Rarence or Logical OR Processor: B086/88 80286 80386/486 Flags: of df if of of 2f af pf cf as a Oo ---asuad Purpose Logically ORs ewo byte, word, or doubleword (80386/486 only) values. Syntas/Example os al, immB or al, adh ‘or ax imma or ax, 1h ‘or regB | memB, immB or B1, Aan or reg | memWW, immW or (word bx}, 6800n or reg | memW, immB or ex, @3n or regB | memB, regB for fbyte bxl, db or reg | memW, regW or dx, ox or regB, regB | mem or bl, bn for regl,regW | memW or dx, {word bx) 80386/486 only cor eax, immDW or eax, e80eveo0en cor regDW | memDW, immDW or ed, for regDW | memDW, immB or (dword bx1, 81h for regDW | memDW, regDW or ex, ocx for regDW, regDW | memDW or cx, (arora bx] Sample Code mov ax, 01234h ax = 01234h fan ax, 0OeFFn or ax, 800eh or dx, 6x 2 Target Continue if cx 0 Description Use or to perform a logical OR on the bits in any two byte, word, of doubleword (80386/486 only) values stored in registers cor in memory variables. (Both of the wo operands can't be memory references.) The corresponding bits in the first operand are sec to 1 only if the bits in either or both of the operands ‘equal I. The first par ofthe sample uses orto ser the MDS of a ‘word value in ax to I, after sh is zeroed by a previous and with a mask of OOOFFh, ‘Another typical use for ois o cest whether a value equals 0, as the second part of the sample demonstrates. ORing a value with itself sets the zero flag t0 1, without changing the original value, only if all bits inthe value are . Note that this also sets both ct land of to 0, a fact that might be useful in some circumstances. See Also and, x0r out Assvaty ancuace Reeence Gut Output to Port Processor: 8086/88 80286 B0386/486 Flags: of df if uf sf af af pf of _ a 4 a ee Purpose (Oueputs values to ports. SyntaxlExample out immB, al out 14n, at out ds, al out dx, al out inimB, ax out @1Fh, ax out di, ax out ox, ax 803861486 only cout fmmB, eax out Fn, ax out ds, eax out x, eax Sample Code ctr18259 €0U 02th; 8269 masks port in al, Ctrle259 ; Read 259 enable masks nd ai, EnablerRO ; Clear nasked bit out ¢trie259, al; write new 6259 masks Description The ovt instruction writes a value in a1, ax, or eax (80386/486 only) toa hardware pore. As the sample shows, out is often used in conjunction with in and logical instructions such as ané and fr to examine and change bit switches at various port addresses in che computer. (This is the same sample shown for se.) The simplest form of out writes a byte in al to an immediate port address in the range 0-255. To access higher port addresses, Specify che addsess in che register. See Also An, outs outs outsb outsd outsw Output From Sing to Port Processor: 8086/88 Purpose Syntax/Example 80286 80386/486 Flags: of df if of sf 2f af pf cf ry rn --- (Outputs a sequence of bytes, words, or doublewords from ‘memory to ports. outs de, erst | memB rep outs ox, (varl us fei | memW rap oat, nord var coutsb 19 operant ep outsd ‘outsw no operands rep outsw 803861486 only ‘outs ds, regDW'| memDWrep outs ox, lovord var] coutsd 0 operands rep outsd 753 754 ©) (ret = awa Sample Code Description See Also 5 Note: don't run thist DATASEG string db ‘A string is @ wonderful thing slen = $-string ‘copeses Rov si, offset string ‘pov ax, Resor popad Pop All General-Purpose Doubleword Registers Processor: 8086/88 80286 80386/486 of sf of af pf of Purpose Syntas/Example Sample Code Description See Aleo a eee Removes registers eat, e61, ebp, esp (discarded), ebx,e4%, ex, and eax from the stack. popad no operand: —popad pusnad + Save general-purpose 32-bit registers } other cose bopad j Restore saved registers Use popad on 80386/486 systems to pop the 32-bit registers ei, 24, 609, #89, ebx, ede, ecx, and eax in that order from the stack. “Although che saved value for esp is removed from the stack, the ‘value is not inserted into esp. Normally, you'll use popas after previously having executed pushad to push these same register values (in the opposite order). The instruction uses 32 bytes of stack space. pop, popa, popt, popfd, push, pusha, pushad, pusht, pushtds pope tag Processor: 8086/88 a 80286 80386/486 Flags: of df if cf sf af af pf cf a nN AaAAAAAAAA Purpose Syntax/Example Sample Code Description See Also Removes all flags from the stack. popf mo operand: popt yor ax, ax; Set ax = C000 push ax j Push ax onto stack pont ; Pop stack into flags, thus } resetting all flags’ to @ Execute popf to remove the top word from the stack and insert the bits in that word into the 8086 flags. Normally, you'll do this after previously executing push to push the flag values, perhaps to preserve the result of a comparison or other instruc- tion, Another use for popt is to remove the flags from the stack, in an interrupt service routine. You can also assign various bit values in a word register, push that register onto the stack, and then execute popf to transfer the bits to the flags, thus setting the flags to your new values. ‘0p, Popa, popad, popfd, push, pusha, pushad, pushf, pushtd opfd Processor: 8086/88 80286 80386/486 a soa Lneince Renee Coee_| Pop Extended Flags Flags: of df if of sf of af pf of fwewwwewws Purpose Syntax/Example Sample Code Description See Also ush Processor: a Removes extended 80386 flags except vm and ct from the stack. popfd no operands poptd pusnea + Save extended fags } other code opts 5 Restore extended flags Execute popfd to remove the two top words from the stack and insert the bits in those words into che 80386/486 extended flag register. Normally, you'll do this after previously executing pushta to push the excended flag values, perhaps to preserve the results of comparison or other instruction. (See popt for other potential uses.) The 80386/486 va (vitual 8086 flag, bit 17) and 7 (cesume fag, bit 16) are not changed by pont. op, Popa, popad, popf, push, push, pushad, pushf, pushtd 8086/88 80286 80386/486 a a Push Onto Stack Flags: of df if of sf af af pf of a ‘Transfers values to the stack. Purpose Syntax/Example Sample Code push reg push ax push memW- push [word be] pusher ler | dls push os 80286, 80386/486 only push fmmB push OFh push fmm W push 256 80386/486 only push regDW° push cox push memDW push [dvord bx} push immDW> push 99999 push fl gs push gs push ax + Save ax on stack push bx } Save bx on stack push ox } save ex on stack {other code that changes ax, bx, cx 757 16 758 Paar ill we Resence Description See Also Processor: 8086/88 Purpose Syntax/Example Sample Code pop ox + Restore original cx op bx Restore original bx op ax | Restore original ax Paes push 99990; Turbo Assenbler incorrectly disallows this 4 €66h, 068 ; SUE you can code the instruction 4d 99909; with these two Lines Use push to cransfer a word or doubleword (80386 only) to the stack. Executing push first decrements the stack pointer by 2 (or by 4 in the case of an 80386 doubleword pust). Then the value of the specified operand is copied into the location addressed by ss:sp, Note tha this causes the stack to grow toward lower- memory addresses. The most common use of push isto save register values onto the stack, a the fist part of the sample demonstrates. Later, pop can be used to remove the saved. values, restoring the original registers Ics legal to push but not to pop the value of the code-segment register ¢s. Also, you can push values from memory, using all the usual addressing modes. Thus, instructions such as push (x) and push {value + si} are legal but often neglected forms ofthe instruction. In addition, the 80286 and 80386/486 processors allow pushing immediate values, for example push @ or push 1, A bug in Turbo Assembler 1.0 prevents pushing 32-bit immedi- ze values with instructions such as push 80000, which produces a “constant too large” error. To circumvent this presumably temporary problem, use the ab and da commands in the second part ofthe sample to insert che machine code for this instruction directly into your program. Pop, Popa, popad, popf, poptd, pusha, pushad, pusht, pushta pusha Push Al Genera Purpose Registers 80286 80386/486 Flags: of df if tf sf af af pf cf a a Transfers registers ax, ex, 6x, bx, 8p, bp, 81, and ot to the stack ppusha mo operand: pusha PROG Anyproc pusna Save general-purpose registers 5 other code ova 5 Restore registers ret } Return to caller NOP Description Use pusta to push registers 0x, 6%, dx, be, sp, bp, si, and ds onto the stack in that order. The value pushed for sp is the value of sp ‘prior co executing pusha. (This value is later discarded by popa, thus having no harmful effet on sp.) Normally, you'll follow pusha with popa to restore the saved registers, most often in a subroutine or interrupt service routine. See Also oP, Popa, popad, popt, poptd, push, pushad, pusht, pushtd pushad Push All General-Purpose Doubleword Registers Processor: BOB6/S8 80286 80386/486 Flags: of df if of sf af af pf of re eee Purpose ‘Transfers registers eax, ecx, 80x, esp, ebp, esi, and eai to the stack. Symtax/Example pushad no operands pushaa Sample Code PROG AnyProc pushes ; Save 82-bit general-purpose registers | otner cose oad + mestore 92-bit registers ret | Return to caller Description Use pusnadto push the B0386/486 32-bie registers ea, 20% €68 bx, esp, ebp, es, and edi onto the stack in that order, The vale pushed for esp isthe value of esp prio executing pusnac. (This ‘alu slater discarded by popad, thus having no harmful effect on sp.) Normally, youl follow pushad with popad to restore the saved registers, most often in a subroutine or interrupt service routine. See Also ‘op, Popa, popad, pop, PoPFE, push, pusha, pusht, pushtd pushf push Flags Processor: 8086/88 80286 80386/486 Flags of df if ef sf of af pl cf a4 a ------- Purpose ‘Transfers the flags to the stack Symtax/Example push no operands gusht Sample Code or 2, } Test whether ax = @ pusht + Save result of comparison } other code that may modify flags pont 5 Restore result of “ort yz Bait i dump af ax was & 759 16 Part Reames 760 Description See Also Execute push co transfer the 8086 16-bit flag register to the stack. Al lg bis well as unused bts are pushed. You can pop this word into a general-purpose register oF Use popf to restore the saved flag bits, perhaps to recover the results of an earlier comparison. 0p. Bopa, Bopae,poPF,poptS, push, pusna, pusnaG,pusntd pushfd Push Extended Flags Processor: 8086/88 80286 80386/486 Flags: of df if ef sf af af pf cf a Purpose ‘Transfers the 80386 extended flags to the stack. Syntan/Example push no operands pants Sumple Cade Foes Description Execute pushté to transfer the 80386/486 32-bit extended flag register to the stack. All flag bits as well as unused bits are pushed. You can pop this doubleword into a general-purpose extended register or use poptd to rescore the saved flag bits, perhaps to eeover te role ofan carer compares See Alo so ppn pops op. ppt buh, ua, pata, pst rel Rotate eft Trough Cary Processor: 8086/88 80286 80386/486 Flags: of df if of sf cf af pf cf ek aoe eee : Purpose Rotates bits leftward through the carry fag. SyntatExample cg | monBe ect nist rgB | memBal tel fabyery et rel reg | memW, 1 rel [aword}, 1 rdmgW moniled Fat et 80286, 0386/48 eat meno reve, « HL moni mB ek (aver, 4 80386/486 only RregbW | momDW, 1 ret eae, 1 rel regDW | memDW, cl red (aword bx), cl KLgDW | memDW SnmBret son, Description See Alo rer Processor: 8086/88 Purpose ‘Syntax/Example Assewery Lancuact Rerence Gor] Use ret to rotate the bits in word, byte, and doubleword (80386/486 only) registers and memory values tothe eft (coward the MSDs) including the cary fag ct as par of che ‘original value, In other words, che old MSD shifts into ot, which Shifts ino the new LSD, while al cher bit shift one poston to the lef, Repeating this action would eventually eestor che original value and ct. For all processors, the second operand specifies the number of bit rotation o perform. On the 8086 and 8088 procesor iF the second opertnd is tera, it must equal 1. To Focate more than one bit you must assign the rotation count ooh and Specify this register asthe second operand. The 80286 and #0386/486 processors allow you co use any immediate value as the second operand, for example a in rel cx, 4 0 rotate ox 4 bits left. The 80386/486 further extends these forms by allowing rotatiors involving 32-bit extended register. ‘When the second operand isan immediate 1 after ret che ot flag equals the exclusive OR of ef and the MSD ofthe newly rotated value Thus. ifor = tafcr rel reg ree, then the Upper 2 bits ofthe original value were ether 11 or 00. One way to tse this Knowledge ico stop a rotation at soon at a1 bit dopa inthe roared value ASD Forcample he nga Yalu in a i 01000000b, executing eel ax, 1 results in of = 8 Ind ex = 100000008, which sets of to 1, a condition that you Gin te with oar ror Tn alter cave when he sco eperand to ret isnot an immediate 1, the of flags not define ‘Also if the rotation count is 0 of and et are left unchanged an oddity ofl practical value. rer, rol, For, al, sar, hl, she 80286 80386/486 Flags: of df if ef sf af af pf of a a au - ------ a Rotates bits rightward through the carry flag, ree rgB | memB, 1 ver aly rer mg | momB, cd rer fabytel, el er reg | mem, 1 rer fawordl, 1 rer regW | memW, cl ror bx, ot 80286, 80386/486 only rer regB | memB, immB rer oh, 4 rer regW | memW, immB rev (awordl, 4 80386/486 only rer regDW | memDW, 1 rer cox, 1 rer regDW | memDW, ol rer (anord bx), ch er regDW | memDW, immB ror ecx, 761 tb6a==—— 762 Sample Code Description See Also rep repe repz 2 Assign rotation count to el rer ax, cl Rotate ax right by count in cl Use rer to rotate the bits in word, byte, and doubleword (80386/486 only) registers and memory values to the right (coward the LSDs) including the carry lag of as part of the al value. In other words, the old LSD shifts into ct, which shifts into the new MSD, while all other bits shift one position, co the let. Repeating this action would eventually restore the original value and cf For all processors, the second operand specifies the number of bic rotations to perform. On the 8086 and 8088 processors, if the second operand is literal, it must equal 1, To rotate more than 1 bit, you must assign the rotation count to and specify this register asthe second operand. The 80286 and 80386/486 processors allow you to use any immediate value as the second ‘operand, for example asin rer ox, 9 to rorate &x 3 bits right. ‘The 80386/486 further extends these forms by allowing rora- tions involving 32-bit extended registers. ‘When the second operand is an immediate 1, after rer the of flag equals the exclusive OR of the two MSDs of the newly rotated value. Thus, fof = 1 after rer reg i men, 1, then ef and the original MSD were different: otherwise, they were both ‘equal to 1 or 0. Stated another way, of = 1 indicates a change in sign of the original value asa result ofthe rotation. In all other ‘cases, when the second operand to rer is not an immediate 1, the of flag is not defined. Also, ifthe rotation count is 0, of and ef are lee unchanged—an oddity of litle practical value. rel, rol, ror, sal, sar, shi, shr Repeat, Repeat While Equal Processor: 8086/88 80286 80386/486 Flags: of df if uf sf 2f af pf cf Purpose Syntax/Example rep mous | moosb | movsw rep nove {byte di}, (byt nN a a -------- Conditionally repeats a string instruction. sil rep stos | stb | stosw rep stose repecmps | empsb | empsw repe eaps (word strt}, (word str} repecmps | empsb | amps repr onpsb repescas | scasb | scaw repe scasw repescas | seasb | scasw repz scas [byte es:ver] 80286, 803861486 only rep ins | insh | insw cep insb rep aus | ousb | outw cep outs &x, word es:si] ‘Asiwary Lancuace RecN Gude Sample Code Description 80386/486 only rep movs | mottd rep novs {aword edt}, [4word esi] rep sts | stosd rep stosd rep ins | id rep ins (Onord var}, repouts | outsd cep outs dx, [ovord si] repecmps | cmpsd rape cxpsd repzcmps | cmpid repr caps Oword stet, (dword ste2] repe seas | pe scasd repescas | sasd rape scas [dword es:esi] UDATASES string db 88 dup (2); Uninitialized variable strlen = §- string Length of string cooese6 ov ax, edata 3 Instialize es nov es, ax segnent register ASSUME” 05:0ROUP Tell tasm where es points ov di, offset string ; Address string with es:di mov cx, strlen } Assign string length to cx ed } Auto-inrenent di mov al, * Assign ASCIT value to al rep stosb j FALL string with blanks ‘The three mnemonics rep, repe, and rep2 represent the same instruction prefix, which may be attached to any string instruc- tion as shown in the examples and the sample code. Even though ‘the mnemonics are identical, the effects differ depending on the strong instruction tha i prefaced. Use rep before movs, stos, ine and ovte— plus the shorthand mnemonics fr these nsruc- tions. Use repe and repz before onps and scas plus shorthand equivalents ‘The rep prefix repeats the string instruction that follows the ‘number of times specified in ex. The repe and repe also repeat @ string instruction by the value in ox but end the repetition if, after any iteration, zf = 0. Thus, you can use these two prefixes to repeat a string compare or scan for a certain number of times or until the string instruction locates a specific value, The toas instruction (and its shorthand mnemonics) may be repeated, although there is never any good reason to do so. (The result of a repeated oes instruction is to load the accumulator with one value ater all repetitions are finished—there is no way to use the intermediate loaded values.) See the various string instructions elsewhere in this chapter for ‘more details and for the operands that you may use wit instructions such as enps, which, for brevity, ae not repeated here. Also although the repeat prefixes are listed here as not changing any’ fg ie aware thet the sing instructions Fllow- ing the prefies can change Hag setngs. enps, ins, mvs, outs, repne, repn2, Seas, stos 16 763 repne repnz Repeat While Not Equal Processor: 8086/88 80286 80386/486 Flags: of df if of sf of af pf of rn Purpose Syntax/Example Sample Code Description See Also repz ry a Conditionally repeats a string compare or scan instruction, repne comps | empib | empaw repre cnps {word strtl, {word ste2] repnz empr | empsb | empsw repnz enpeb repne seas | scab | seasw —repne scasw repneseas | scab | scaw repnz seas [byte es:var] 80386/486 only repne cmps | cmpid _repne eapsa epnzcmps | ompid repnz emps [dword strt], (dword str 2] repnescas | saad repne scasd repnz-scas | sad —_repnz cas. {dword es:esil DATASEG string ob “Thisstringhasn’ tanyolanks. serie string coveses nov ax, @data =; Initialize es ov es, ax } segnent register ASSUME’ o5:00ROUP _; Tell tesa were es points ov di, offset string + strien - 1 ; Adgress end of string mov ex, strlen; Assign string Length to cx eed ‘Auto-decronent ot mov al, Value to search for repne scasb joxz Exit Scan for planks Exit if no blanks found ‘adcresees Last nonblank The reone and repnz prefixes, both of which represent the same machine code, repeat a caps or seas string instruction (plus shorchand mnemonics) for the number of times specified in ex but end the repetitions early ifan iteration secs 2# = 1. For more decals, see the notes for repe and repz, which operate similarly but recognize the opposite flag value for 2¢. The example demonstrates how to use repne ro scan a string from back to front, leaving a addressing the last nonblank in the string or, if no blanks were found, jumping to label Exit (not shown). ens, ins, mvs, outs, rep, repe, repz, seas, stos Repeat While Zero Processor: 8086/88 80286 80386/486 Flags: of df if ef of of af pf of rn 764 a a rep ver ret retf retn oy Return, Return Far or Near Processor: 8086/88 a 80286 80386/486 Flags: of df if of sf 2f af pf cf a “ —-------- Purpose Syntax/Example Sample Code Description See Also Returns from a subroutine procedure. et no operands rat rn natpenends eta ethno operands ret rein mee recn ims retn 16 rect immW rett 4 POG AnyProe + procedure code ret j Return to caller ENDP AnyProc The three ret mnemonics are typically used as the final instruc tion of a procedure activated by e211. Both ret and ret, which are synonyms for the same instruction, pop the 16-bit return addvess from the stack into register 1p, continuing the program with the instruction that follows the ca12, which previously pushed this address onto the stack before activating the proce- dure. The ret instruction pops two words from the stack, ‘signing the fist word to cand the second cp, Thus the program continues in a different code segment, Use rett ony you made a far cal to the subroutine, usually by using the instruction e811 FAR AnyProc. ‘When using simplified memory models (asin most ofthis book's example programs), i's probably best use only ret. This lets ‘Turbo Assembler decide whether to assemble the code for cetf or retn as needed and also to use the appropriate cal! instruction, You can force near and far calls and returns, but be aware that using rett when you should have used retn will undoubredly cause a system crash sooner or later—probably sooner. ‘You may follow any of the three mnemonics with an unsigned value, which will be added to the stack pointe afier the return address is popped. High-level languages such as Pascal use this form of ret to end procedures and functions to which param- ‘eters have been passed on the stack. Adjusting the stack pointer swith ret lets the procedure itself remove the stacked parameters, instead of leaving it to the calling code. Because the optional value added to ret is immediate (fixed) the method is not 2s helpful in languages such as C, which allow a variable number of parameters to be passed to functions call 765 Pact ae Reever rol Route Processor: 8086/88 80286 80386/486 Flags:of df if of sf af af pf cf aa 4 au a Purpose Rotates bits lefwa Syntax/Example rol regB | memB, 1 rol ah, 1 rol vB | memB, cl rol tabytel, et rol regW | memWW, 1 rol lavoral, + rol egW | memW, cl ro bey 80286, 803861486 only rol regB | memB, immB rod dh, 4 rol reg’ | memW, immB rol (aword), 80386/486 only rol regDW | memDW, 1 rol eax, 1 rol regDW/| memDW, cl coh {dword bx}, ed rol regDW | memDW, immB coh ecx. 4 Sample Code ov cy 5 + Load count anto cl rol [aword), el } Rotate word left 5 tines Description Use rol to rotate the bits in word, byte, and doubleword. (80386/486 only) registers and memory values to the left (‘coward the MSDs). The old MSD shifts into the new LSD position while all other bits shift one position to the left. In Addition, the old MSD is copied into ef. Repeating this action ‘would eventually estore the original value but not necessarily restore cf. (This is nearly identical vo the way rel operates, ‘except that of is not treated as an extra bitin the rotated value.) For all processors, the second operand specifies the number of bit rotations to perform. On the 8086 and 8088 processors, if the second operand is literal, ic must equal 1. To rotate more than I bit, you must assign the rotation count to ed and specify this register as the second operand. The 80286 and 80386/486 processors allow you to use any immediate value as the second ‘operand, for example asin rot ax, 2 to rotate ox 2 bits lef. The 80386/486 further extends these forms by allowing rorations involving 32-bit extended registers. ‘When the second operand is an immediate 1, after rot the of flag equals the exclusive OR of ef and the MSD of the newly rotated value, (See ret for an expanded discussion of these flag values.) In all other cases, when the second operand to re} is not an immediate 1, the of flag is not defined. Also, ifthe rotation count is 0, of and of are left unchanged—an oddity of litde practical value. Of more use might be the associated fact that, afer every ot, of equals the LSD of the newly rotated value. 766 See Also rel, rer, rar, sal, 6ar, sh, shr ror Assay Lancuace Rene Guine | Rotate Right Processor: 8086/88 a Purpose Syntax/Esample Sample Code Description 80286 80386/486 Flags: of df if of sf of af pf of a nN re a Rotates bits rightward. ror regB | memB, 1 ror al, 1 ror regB | memB, cl ror {abyte), ot ror reg | memW, 1 ror faword), 1 ror reg | memW, ef ror bx, cl 80286, 80386/486 only ror regB | memB, immB ror ah, ¢ ror reg | memVW, immB ror {aword), & 80386/486 only ror regDW | memDW,1 ror eax, 1 ror regDW | memDW, cl ror {dword bx, ch ror regDW | memDW, immB cor ecx, 4 mov cl, 8 + Load count into et ror ax, cl } Rotate ax right & tines (Wote: this is the sane a3 xeng am, alt) Use ror ro rotate the bits in word, byre, and doubleword (80386/486 only) registers and memory values to the right (toward the LSDs). The old LSD shifis into the new MSD position while al other bits shift one position ro the r addition, the old LSD is copied into et. Repeating this action would eventually restore the original value, but not necessarily restore ef. (This is nearly identical to the way rer operates, except that ef is not treated as an extra bie in the rotated value) For all processors, the second operand specifies the number of bic rotations to perform. On the 8086 and 8088 processos, if the second operand is litera, it must equal 1. To rotate more than L bit, you must assign the rotation count to ¢3 and specify this register as the second operand. The 80286 and 80386/486 processors allow you to use any immediate value asthe second ‘operand, for example as in ror an, 4 t0 rotate an 4 bits right. ‘The 80386/486 further extends these forms by allowing rota tions involving 32-bit extended registers. When the second operand is an immediate |. after ror the of flag equals the exclusive OR of the two MSDs of che newly. rotated value. Thus, fof = 1 after cor reg i nen, 1, then the original LSD and MSD bits were different; otherwise, these ewo end bits in the value were both equal to 1 or 0. In all other cases, when the second operand to ror is not an immediate 1, the of flag is not defined. Also, if che rotation count is 0, of and ef are left unchanged—an oddity of litte practical value. Of more use 767 1 6 cares 768 See Also sahf Processor: 8086/88 a Purpose Syntax/Example Sample Code ‘might be the associated fact that, after every ror, of equals the MSD ofthe newiy rotated value rol, rer, rol, 88, ser, sm, shr Store ah Register to Fags 80286 80386/486 Flags: of df if ef sf of af pf cf a a aaaaa Copies bits 7, 6, 4, 2, and 0 from ah to the marked flags. sabf no operands sant or ah, ah 5 Zero an sant } Zero st, 2f, af, pt, ef Description See Also sal Processor: 8086/88 a Purpose Syntax/Example Execute sahf to store bits from an into five flags. With bit numbers in parentheses, the affected flags are s¢(7), 2f(6), af(4), pt(2), and et(0). Other flags are not affected. The instruction is Sometimes used in conjunction with a math coprocessor. rent Shift Arithmetic Left 80286 80386/486 Flags: of df if cf sf of af pf cf rn a av aaua Shifts bits leFoward. sal regB | memB, 1 sal (abyte], 1 sal regB | memB, cl sal ax, cl sal regW | memlW, 1 sal dx, 1 Sample Code sal regW | memW, el sal (aword + bx), el 80286, 80386/486 only sal regB | memB, immB sal reg | memW, immB 5 80386/486 only sal regDW | memDW, 1 sai eax, + sal regDW | memDW, cl sah (dword es:di1, cb (word bp + 4], 4 sal regDW | memDW, immB sai (anord oxl, 4 DOATASES value od 12548676 Goubleword value oveses shi (word val rel (word value + 2), 1 ye Bat to be multiplied by 2 J) 15 Shitt-Low order wore nif high-order word junp Af overflow detected See Also sar Processor: 8086/88 a Assay Lancunce Resence Gui ‘The sat and sh mnemonics are synonyms for the same instruc- tion and generate the identical machine code. Normally, you'll use #01 co multiply unsigned values by powers of 2 and sht co simply shife bits let into position. Using sa} lends additional clarity to a program by indicating a mathematical shife, bt you can use the two mnemonics interchangeably. Executing sa1 or st shifis the old MSD of the value into the carry flag. A zero bit shifts into the new LSD. Repeating this action eventually sets ll bits in the specified register or memory location to 0. When the second operand is an immediate 1, after shifting, of = 1 only ifthe new ef does not equal the new MSD. Ifo then the new ef and MSD bits are different. You might use this knowledge to detect a zero bie shifting into the MSD position of, an initially nonzero value. When the second operand is not an immediate 1, of is not defined. ‘The sample shows how to use word shifts and rotations (see rot) to multiply a doubleword value by 2. The intial shi shifts the low-order word, copying the MSD into of. Then, ret rotates the high-order word, shifting in of o the new LSD (of the high- order word). Subsequent ret instructions could be added to shift even larger muleibyte values. Ifafier the inal re che carry flag equals 1, then an overflow has occurred. rel, rer, rol, ror, sar, shi, shr Shift Arithmetic Right 80286 80386/486 Flags: of df if of sf af af pf cf Purpose Syntax/Example a nN au---aAau AA Shifts bits rightward. sar regB | memB, 1 sar bl, 4 sar regB | memB, cl sar ch, el sar regW | memW, 1 sar [awora}, 1 sar regW | memW, cl sar {word bx}, 2 80286, 80386/486 sar regB | memB, immB sar (byte bp + 2), 4 sar regW |_memW, immB sar ax, 4 80386/486 only sar regDW | memDW, 1 sar {éword bp - 8], 1 sar regDW | memDW, cl sar eax, cL sar regDW | memDW, immB sar ed, 16 16 769

You might also like