80386 Instruction Set

11.3.5 80386 Instruction Set

The 80386 can execute all 16-bit instructions in real and protected modes. This is provided in order to make the 80386 software compatible with the 8086. The 80386 uses either 8- or 32-bit displacements and any register as the base or index register while executing 32-bit code. However, the 80386 uses either 8- or 16-bit displacements with the base and index registers while executing 16-bit code. The base and index registers utilized by the 80386 for 16- and 32-bit addresses are as follows:

image

In the following, the symbol ( ) will indicate the contents of a register or a memory location. A description of some of the new 80386 instructions is given next.

1. Arithmetic Instructions

There are two new sign extension instructions beyond those of the 8086.

CWDE      Sign-extend 16 bit contents of AX to a 32-bit double word in EAX.

CDQ        Sign-extend a double word (32 bits) in EAX to a quadword (64 bits) in EDX:EAX

The 80386 includes all of the 8086 arithmetic instructions plus some new ones. Two of the instructions are as follows:

image

The unsigned multiplication MUL instruction has the same operands as IMUL.

The 80386 divide instructions include all of the 8086 instructions plus some new ones. Some of them are listed next:

image

2. Bit Instructions

image

BSF scans (checks) the 16-bit (word) or 32-bit (double word) number defined by s from right to left (bit 0 to bit 15 or bit 31). The bit number of the first 1 found is stored in d. If the whole 16-bit or 32-bit number is 0, the ZF flag is set to 1; Otherwise, ZF = 0. For example, consider BSF EBX, EDX. If (EDX) = 01241240 16, then after BSF EBX, EDX, (EBX) = 00000006 16 and ZF = 0. The bit number 6 in EDX (contained in the second nibble of EDX) is the first 1 found when (EDX) is scanned from the right.

BSR (bit scan reverse) takes the form

image

BSR scans (checks) the 16-bit or 32-bit number defined by s from the most significant bit (bit 15 or bit 31) to the least significant bit (bit 0). The destination operand d is loaded with the bit index (bit number) of the first set bit. If the bits in the number are all O's, ZF is set to 1 and operand dis undefined; ZF is reset to 0 if a 1 is found.

BT (bit test) takes the form

image

BT assigns the bit value of operand d (base) specified by operands (bit offset) to the carry flag. Only CF is affected. If operands is an immediate data, only 8 bits are allowed in the instruction. This operand is taken modulo 32 so that the range of immediate bit offset is from 0 to 31. This permits any bit within a register to be selected. If dis a register, the bit value assigned to CF is defined by the value of the bit number defined by s taken modulo the register size (16 or 32). If dis a memory bit string, the desired 16 bits or 32 bits can be determined by adding s (bit index) divided by the operand size (16 or 32) to the memory address of d. The bit within this 16- or 32-bit word is defined by d taken modulo the operand size ( 16 or 32). If d is a memory operand, the 80386 may access 4 bytes in memory starting at effective address plus 4 x [bit offset divided by 32]. As an example, consider BT ex, DX. If (CX) = 081F and (DX) = 0021 16,then after BT ex, DX, because the contents of DX is 3310, the bit number 1 [remainder of33/16 = 1 of CX (value 1)] is reflected in CF and therefore, CF= 1.

BTC (bit test and complement) takes the form

BTC       d,         s

where d and s have the same definitions as for the BT instruction. The bit of d defined by sis reflected in CF. After CF is assigned, the same bit of d defined by sis ones complemented. The 80386 determines the bit number from s (whether s is immediate data or register) and d (whether dis register or memory bit string) in the same way as for the BT instruction.

BTR         d,             s

Where d and s have the same definitions as for the BT instruction. The bit of d defined by s is reflected in CF. After CF is assigned, the same bit of d defined by s is reset to 0. Everything else applicable to the BT instruction also applies to BTR.

BTS          d,          s

BTS is the same as BTR except that the specified bit in dis set to 1 after the bit value of d defined by sis reflected in CF. Everything else applicable to the BT instruction also applies to BTS.

3. Set Byte on Condition Instructions

These instructions set a byte to 1 or reset a byte to 0 depending on any of the 16 conditions defined by the status flags. The byte may be located in memory or in a 1-byte general register. These instructions are very useful in implementing Boolean expressions in high-level languages. The general structure of these instructions is SET cc (set byte on condition cc), which sets a byte to 1 if condition cc is true or else resets the byte to 0.

As an example, consider SETB BL (set byte if below; CF = 1). If (BL) = 5216 and CF = I, then, after this instruction is executed, (BL) = 01 16 and eF remains at I ; all other flags (OF, SF, ZF, AF, PF) are undefined. On the other hand, if eF = 0, then, after execution of this instruction, (BL) = 0016, CF = 0, and ZF = 1; all other flags are undefined. The other SET cc instructions can similarly be explained.

4. Conditional Jumps and Loops

JECXZ disp8 jumps if [ECX] = 0; disp8 means a relative address. JECxz tests the contents of the ECX register for zero and not the flags. If [ECX] = 0, then, after execution of the JECXZ instruction, the program branches with a signed 8-bit relative offset(+ 12710 to -128 10 with 0 being positive) defined by disp8. The JECXZ instruction is useful at the beginning of a conditional loop that terminates with a conditional loop instruction such as LOOPNE label. JECXZ prevents entering the loop with [ECX] = 0, which would cause the loop to execute up to 232 times instead of zero times.

The loop instructions are listed next:

image

image

The 80386 loop instructions are similar to those of the 8086 except that if the counter is more than 16 bits, the ECX register is used as the counter.

5. Data Transfer Instructions

a. Move Instructions

The move instructions are described as follows:

imageMOVSX reads the contents of the effective address or register as a byte or a word from the source, sign-extends the value to the operand size of the destination (16 or 32 bits), and stores the result in the destination. No flags are affected. MOVZX, on the other hand, reads the contents of the effective address or register as a byte or a word, zero-extends the value to the operand size of the destination (16 or 32 bits), and stores the result in the destination. No flags are affected. For example, consider MOVSX BX, CL. If (CL) = 8116 and (BX) = 21AF 16, then, after execution of this MOVSX, register BX contains FF81 16 and the contents of CL do not change. Now, consider MOVZX ex, OH. If (CX) = F237 16 and (DH) = 8516, then, after execution of this MOVZX, register CX contains 008516 and DH contents do not change.

b. Push and Pop Instructions

There are new push and pop instructions in the 80386 beyond those of the 8086: PUSHAO and POPAO. PUSHAO saves all 32-bit general registers (the order is EAX, ECX, EDX, EBX, original ESP, EBP, ESI, and EDI) onto the 80386 stack. PUSHAO decrements the stack pointer (ESP) by 3210 to hold the eight 32-bit values. No flags are affected. POPAO reverses a previous PUSHAO. It pops the eight 32-bit registers (the order is EDI, ESI, EBP, ESP, EBX, EDX, ECX, and EAX). The ESP value is discarded instead of loading onto ESP. No flags are affected. Note that ESP is actually popped but thrown away so that (ESP), after popping all the registers, will be incremented by 3210

c. Load Pointer Instructions

There are five instructions in the load pointer instruction category: LOS, LES, LFS, LGS, and LSS. The 80386 can have four versions for each one of these instructions as follows:

image

Note that mem 16:mem 16or mem 16:mem32 defines a memory operand containing the pointers composed of two numbers. The number to the left of the colon corresponds to the pointer's segment selector; the number to the right corresponds to the offset. These instructions read a full pointer from memory and store it in the selected segment register:specified register. The instruction loads 16 bits into DS (for LOS) or into ES (for LES). The other register loaded is 32 bits for 32-bit operand size and 16 bits for 16-bit operand size. The 16- and 32-bit registers to be loaded are determined by the reg16 or reg32 register specified.

The three instructions LFS, LGS, and LSS are associated with segment registers FS, GS, and SS can similarly be explained.

6. Flag Control Instructions

There are two new flag control instructions in the 80386 beyond those of the 8086: PUSHFD and POPFD. PUSHFD decrements the stack pointer by 4 and saves the 80386 EFLAGS register to the new top of the stack. No flags are affected. POPFD pops the 32 bits (double word) from the top of the stack and stores the value in EFLAGS. All flags except VM and RF are affected.

7. Logical Instructions

There are new logical instructions in the 80386 beyond those of the 8086:

image

For both SHLD and SHRD, the shift count is defined by the low 5 bits, so shifts from 0 to 31 can be obtained.

SHLD shifts the contents of d:s by the specified shift count with the result stored back into d; dis shifted to the left by the shift count with the low-order bits of d filled from the high-order bits of s. The bits ins are not altered after shifting. The carry flag becomes the value of the bit shifted out of the most significant bit of d. If the shift count is zero, this instruction works as an NOP. For the specified shift count, the SF, ZF, and PF flags are set according to the result in d. CF is set to the value of the last bit shifted out. OF and AF are undefined.

SHRD shifts the contents of d:s by the specified shift count to the right with the result stored back into d. The bits in dare shifted right by the shift count, with the high­ order bits filled from the low-order bits of s. The bits ins are not altered after shifting. If the shift count is zero, this instruction operates as an NOP. For the specified shift count, the SF, ZF, and PF flags are set according to the value of the result. CF is set to the value of the last bit shifted out. OF and AF are undefined.

As an example, consider SHLD BX, DX, 2. lf(BX) = 183F16 and (DX) = 0IFI 16, then, after this SHLD, (BX) = 60FC 16, (DX) = 01Fl 16, CF = 0, SF= 0, ZF = 0, and PF = 1. Similarly, the SHRD instruction can be illustrated.

8. String Instructions

a. Compare String Instructions

A new 80386 instruction, CMPS mem32, mem32 (or CMPSD) beyond the compare string instructions available with the 8086 compares 32-bit words ES:EDI (second operand) with DS:ESI and affects the flags. The direction of subtraction of CMPS is (ESI) - (EDI). The left operand (ESI) is the source, and the right operand (EDI) is the destination. This is a reverse of the normal Intel convention in which the left operand is the destination and the right operand is the source. This is true for byte (CMPSB) or word (CMPSW) compare instructions. The result of subtraction is not stored; only the flags are affected. For the first operand (ESI), DS is used as the segment register unless a segment override byte is present; for the second operand (EDI), ES must be used as the segment register and cannot be overridden. ESI and EDI are incremented by 4 if DF = 0 and are decremented by 4 if DF = 1. CMPSD can be preceded by the REPE or REPNE prefix for block comparison. All flags are affected.

b. Load and Move String Instructions

There are new load and move instructions in the 80386 beyond those of 8086. These are LODS mem32 (or LODSD) and MOVS mem32, mem32 (or MOVSD). LODSD loads the (32-bit) double word from a memory location specified by DS: ESI into EAX. After the load, ESI is automatically incremented by 4 if DF = 0 and decremented by 4 if DF = I. No flags are affected. LO DS can be preceded by the REP prefix. LODS is typically used within a loop structure because further processing of the data moved into EAX is normally required. MOVSD copies the (32-bit) double word at the memory location addressed by DS:ESI to the memory location at ES:EDI. DS is used as the segment register for the source and may be overridden. After the move, ESI and EDI are incremented by 4 if DF = 0 and are decremented by 4 if DF = 1. MOVS can be preceded by the REP prefix for block movement of ECX double words. No flags are affected.

c. String I/O Instructions

There are new string I/O instructions in the 80386 beyond those of the 8086: INS mem32, DX (or INSD) and OUTS DX, mem32 {or OUTS D). INSD inputs 32-bit data from a port addressed by the contents of DX into a memory location specified by ES:EDI. ES cannot be overridden. After data transfer, EDI is automatically incremented by 4 if DF = 0 and decremented by 4 if DF = 1. INSD can be preceded by the REP prefix for block input of ECX double words. No flags are affected. OUTSD outputs 32-bit data from a memory location addressed by DS: ESI to a port addressed by the contents of DX. DS can be overridden. After data transfer, ESI is incremented by 4 if DF = 0 and decremented by 4 if DF =

1. OUTS D can be preceded by the REP prefix for block output of ECX double words.

d. Store and Scan String Instructions

There is a new 80386 STOS mem32 (or STOSD) instruction. STOS stores the contents of the EAX register to a double word addressed by ES and EDI. ES cannot be overridden. After the storage, EDI is automatically incremented by

4 if DF = 0 and decremented by 4 if DF = I. No flags are affected. STOS can be preceded by the REP prefix for a block fill of ECX double words. There is also a new scan instruction, the SCAS mem32 (or SCASD) in the 80386. SCASD performs the 32-bit subtraction (EAX) - [memory addressed by ES and EDI]. The result of subtraction is not stored, and the flags are affected. SCASD can be preceded by the REPE or REPNE prefix for block search of ECX double words. All flags are affected.

e. Table Look-Up Translation Instruction

A modified version of the 8086 XLAT instruction is available in the 80386. XLAT mem8 (XLATB) replaces the AL register from the table index to the table entry. AL should be the unsigned index into a table addressed by DS:BX for a 16-bit address and by DS:EBX for the 32-bit address. DS can be overridden. No flags are affected.

9. High-Level Language Instructions

Three instructions, ENTER, LEAVE, and BOUND, are included in the 80386. The ENTER imm16,imm8 instruction creates a stack frame. The data imm8 defines the nesting depth of the subroutine and can be from 0 to 31. The value 0 specifies the first subroutine only. The data imm8 defines the number of stack frame pointers copied into the new stack frame from the preceding frame. After the instruction is executed, the 80386 uses EBP as the current frame pointer and ESP as the current stack pointer. The data imm16 specifies the number of bytes of local variables for which the stack space is to be allocated. If imm8 is zero, ENTER pushes the frame pointer EBP onto the stack; ENTER then subtracts the first operand imm16 from the ESP and sets EBP to the current ESP.

For example, a procedure with 28 bytes of local variables would have an ENTER 2 8 , 0 instruction at its entry point and a LEAVE instruction before every RET. The 28 local bytes would be addressed as offset from EBP. Note that the LEAVE instruction sets ESP TO EBP and then pops EBP. The 80386 uses BP (low 16 bits of EBP) and SP (low 16 bits of ESP) for 16-bit operands and uses EBP and ESP for 32-bit operands.

The BOUND instruction ensures that a signed array index is within the limits specified by a block of memory containing an upper and lower bound. The 80386 provides two forms of the BOUND instruction:

BOUND reg16,              mem32

BOUND reg32,              mem64

The first form is for 16-bit operands. The second form is for 32-bit operands and is included in the 80386 instruction set. For example, consider BOUND EDI, AD DR. Suppose (ADDR) = 32-bit lower bound d1 and (ADDR + 4) = 32 bit upper bound d". If, after execution of this instruction, (EDI) <d1 or>d, the 80386 traps to interrupt 5; otherwise, the array is accessed.

The BOUND instruction is usually placed following the computation of an index value to ensure that the limits of the index value are not violated. This permits a check to determine whether or not an address of an array being accessed is within the array boundaries when the register indirect with index mode is used to access an array element. For example, the following instruction sequence will allow accessing an array with base address in ESI, the index value in EDI, and an array lenght 50 bytes; assuming the 32-bit contents of memory location, 20000100 16 and 20000104 16 are 0 and 49, respectively:

imageExample 11.1

Determine the effect of each of the following 80386 instructions:

(a) CDQ

(b) BTC CX, BX

(c) MOVSX ECX, E7H

Assume (EAX) = FFFFFFFFH, (ECX) = F 1257124H, (EDX) = EEEEEEEEH, and (BX) = 0004H prior to execution of each of these given instructions.

Solution

(a) After CDQ,

(EAX) = FFFFFFFFH

(EDX) = FFFFFFFFH

(b) After BTC ex, BX, bit4 of register CX is reflected in CF and then ones complemented in CX , as is shown below.

image

(c) MOVSX ECX, E7H copies the 8-bit data E7H into the low byte of ECX and then sign­ extends to 32 bits. Therefore, after MOVSX ECX, E7H,

(ECX) = FFFFFFE7H

Example 11.2

Write an 80386 assembly language program to multiply a signed 8-bit number in AL by a signed 32-bit number in ECX. Assume that the segment registers are already initialized. Solution

imageExample 11.3

Write an 80386 assembly language program to move two columns of ten thousand 32-bit numbers from A (i) to B (i). In other words, move A (1) to B (1), A (2) to B (2), and so on.

Solution

image

image

Labels: