• 沒有找到結果。

Programming With General-Purpose

CHAPTER 7 PROGRAMMING WITH

7.3 SUMMARY OF GP INSTRUCTIONS

7.3.1. Data Transfer Instructions

The data transfer instructions move bytes, words, doublewords, or quadwords both between memory and the processor’s registers and between registers. For the purpose of this discussion, these instructions are divided into subordinate subgroups that provide for:

General data movement

Exchange

Stack manipulation

Type conversion

7-4 Vol. 1

PROGRAMMING WITH GENERAL-PURPOSE INSTRUCTIONS

7.3.1.1 General Data Movement Instructions

Move instructions — The MOV (move) and CMOVcc (conditional move) instructions transfer data between memory and registers or between registers.

The MOV instruction performs basic load data and store data operations between memory and the processor’s registers and data movement operations between registers. It handles data trans-fers along the paths listed in Table 7-1. (See “MOV—Move to/from Control Registers” and

“MOV—Move to/from Debug Registers” in Chapter 3, Instruction Set Reference A-M of the IA-32 Intel Architecture Software Developer’s Manual, Volume 2A for information on moving data to and from the control and debug registers.)

The MOV instruction cannot move data from one memory location to another or from one segment register to another segment register. Memory-to-memory moves are performed with the MOVS (string move) instruction (see Section 7.3.9., “String Operations”).

Conditional move instructions — The CMOVcc instructions are a group of instructions that check the state of the status flags in the EFLAGS register and perform a move operation if the flags are in a specified state. These instructions can be used to move a 16-bit or 32-bit value from memory to a general-purpose register or from one general-purpose register to another. The flag state being tested is specified with a condition code (cc) associated with the instruction. If the condition is not satisfied, a move is not performed and execution continues with the instruction following the CMOVcc instruction.

Table 7-2 shows mnemonics for CMOVcc instructions and the conditions being tested for each instruction. The condition code mnemonics are appended to the letters “CMOV” to form the mnemonics for CMOVcc instructions. The instructions listed in Table 7-2 as pairs (for example, CMOVA/CMOVNBE) are alternate names for the same instruction. The assembler provides these alternate names to make it easier to read program listings.

Table 7-1. Move Instruction Operations Type of Data Movement Source → Destination

From memory to a register Memory location → General-purpose register Memory location → Segment register From a register to memory General-purpose register → Memory location

Segment register → Memory location

Between registers General-purpose register → General-purpose register General-purpose register → Segment register Segment register → General-purpose register General-purpose register → Control register Control register → General-purpose register General-purpose register → Debug register Debug register → General-purpose register Immediate data to a register Immediate → General-purpose register Immediate data to memory Immediate → Memory location

Vol. 1 7-5 PROGRAMMING WITH GENERAL-PURPOSE INSTRUCTIONS

CMOVcc instructions are useful for optimizing small IF constructions. They also help eliminate branching overhead for IF statements and the possibility of branch mispredictions by the processor.

These conditional move instructions are supported in the P6 family, Pentium 4, and Intel Xeon processors. Software can check if CMOVcc instructions are supported by checking the processor’s feature information with the CPUID instruction.

7.3.1.2 Exchange Instructions

The exchange instructions swap the contents of one or more operands and, in some cases, perform additional operations such as asserting the LOCK signal or modifying flags in the EFLAGS register.

The XCHG (exchange) instruction swaps the contents of two operands. This instruction takes the place of three MOV instructions and does not require a temporary location to save the contents of one operand location while the other is being loaded. When a memory operand is used with the XCHG instruction, the processor’s LOCK signal is automatically asserted. This instruction is thus useful for implementing semaphores or similar data structures for process synchronization. See “Bus Locking” in Chapter 7 of the IA-32 Intel Architecture Software Developer’s Manual, Volume 3 for more information on bus locking.

The BSWAP (byte swap) instruction reverses the byte order in a 32-bit register operand. Bit positions 0 through 7 are exchanged with 24 through 31, and bit positions 8 through 15 are exchanged with 16 through 23. Executing this instruction twice in a row leaves the register with the same value as before. The BSWAP instruction is useful for converting between “big-endian”

and “little-endian” data formats. This instruction also speeds execution of decimal arithmetic.

(The XCHG instruction can be used to swap the bytes in a word.) Table 7-2. Conditional Move Instructions

Instruction Mnemonic Status Flag States Condition Description Unsigned Conditional Moves

CMOVA/CMOVNBE (CF or ZF) =0 Above/not below or equal

CMOVAE/CMOVNB CF = 0 Above or equal/not below

CMOVNC CF = 0 Not carry

CMOVB/CMOVNAE CF = 1 Below/not above or equal

CMOVC CF = 1 Carry

CMOVBE/CMOVNA (CF or ZF) = 1 Below or equal/not above

CMOVE/CMOVZ ZF = 1 Equal/zero

CMOVNE/CMOVNZ ZF = 0 Not equal/not zero

CMOVP/CMOVPE PF = 1 Parity/parity even

CMOVNP/CMOVPO PF = 0 Not parity/parity odd

7-6 Vol. 1

PROGRAMMING WITH GENERAL-PURPOSE INSTRUCTIONS

The XADD (exchange and add) instruction swaps two operands and then stores the sum of the two operands in the destination operand. The status flags in the EFLAGS register indicate the result of the addition. This instruction can be combined with the LOCK prefix (see

“LOCK—Assert LOCK# Signal Prefix” in Chapter 3, Instruction Set Reference A-M of the IA-32 Intel Architecture Software Developer’s Manual, Volume 2A) in a multiprocessing system to allow multiple processors to execute one DO loop.

The CMPXCHG (compare and exchange) and CMPXCHG8B (compare and exchange 8 bytes) instructions are used to synchronize operations in systems that use multiple processors. The CMPXCHG instruction requires three operands: a source operand in a register, another source operand in the EAX register, and a destination operand. If the values contained in the destination operand and the EAX register are equal, the destination operand is replaced with the value of the other source operand (the value not in the EAX register). Otherwise, the original value of the destination operand is loaded in the EAX register. The status flags in the EFLAGS register reflect the result that would have been obtained by subtracting the destination operand from the value in the EAX register.

The CMPXCHG instruction is commonly used for testing and modifying semaphores. It checks to see if a semaphore is free. If the semaphore is free, it is marked allocated; otherwise it gets the ID of the current owner. This is all done in one uninterruptible operation. In a single-processor system, the CMPXCHG instruction eliminates the need to switch to protection level 0 (to disable interrupts) before executing multiple instructions to test and modify a semaphore.

For multiple processor systems, CMPXCHG can be combined with the LOCK prefix to perform the compare and exchange operation atomically. (See “Locked Atomic Operations” in Chapter 7 of the IA-32 Intel Architecture Software Developer’s Manual, Volume 3 for more information on atomic operations.)

The CMPXCHG8B instruction also requires three operands: a 64-bit value in EDX:EAX, a 64-bit value in ECX:EBX, and a destination operand in memory. The instruction compares the 64-bit value in the EDX:EAX registers with the destination operand. If they are equal, the 64-bit value in the ECX:EBX register is stored in the destination operand. If the EDX:EAX register and the destination are not equal, the destination is loaded in the EDX:EAX register. The

Instruction Mnemonic Status Flag States Condition Description Signed Conditional Moves

CMOVGE/CMOVNL (SF xor OF) = 0 Greater or equal/not less

CMOVL/CMOVNGE (SF xor OF) = 1 Less/not greater or equal

CMOVLE/CMOVNG ((SF xor OF) or ZF) = 1 Less or equal/not greater

CMOVO OF = 1 Overflow

CMOVNO OF = 0 Not overflow

CMOVS SF = 1 Sign (negative)

CMOVNS SF = 0 Not sign (non-negative)

Table 7-2. Conditional Move Instructions (Contd.)

Vol. 1 7-7 PROGRAMMING WITH GENERAL-PURPOSE INSTRUCTIONS

CMPXCHG8B instruction can be combined with the LOCK prefix to perform the operation atomically.

7.3.1.3 Exchange Instructions in 64-Bit Mode

The CMPXCHG16B instruction is available in 64-bit mode only. It is an extension of the func-tionality provided by CMPXCHG8B that operates on 128-bits of data.

7.3.1.4 Stack Manipulation Instructions

The PUSH, POP, PUSHA (push all registers), and POPA (pop all registers) instructions move data to and from the stack. The PUSH instruction decrements the stack pointer (contained in the ESP register), then copies the source operand to the top of stack (see Figure 7-1). It operates on memory operands, immediate operands, and register operands (including segment registers).

The PUSH instruction is commonly used to place parameters on the stack before calling a proce-dure. It can also be used to reserve space on the stack for temporary variables.

The PUSHA instruction saves the contents of the eight general-purpose registers on the stack (see Figure 7-2). This instruction simplifies procedure calls by reducing the number of instruc-tions required to save the contents of the general-purpose registers. The registers are pushed on the stack in the following order: EAX, ECX, EDX, EBX, the initial value of ESP before EAX was pushed, EBP, ESI, and EDI.

Figure 7-1. Operation of the PUSH Instruction Stack 0

31

Before Pushing Doubleword Growth

ESP n − 4

n − 8 n

Stack

31 0

After Pushing Doubleword

ESP Doubleword Value

7-8 Vol. 1

PROGRAMMING WITH GENERAL-PURPOSE INSTRUCTIONS

The POP instruction copies the word or doubleword at the current top of stack (indicated by the ESP register) to the location specified with the destination operand. It then increments the ESP register to point to the new top of stack (see Figure 7-3). The destination operand may specify a general-purpose register, a segment register, or a memory location.

The POPA instruction reverses the effect of the PUSHA instruction. It pops the top eight words or doublewords from the top of the stack into the general-purpose registers, except for the ESP register (see Figure 7-4). If the operand-size attribute is 32, the doublewords on the stack are transferred to the registers in the following order: EDI, ESI, EBP, ignore doubleword, EBX, EDX, ECX, and EAX. The ESP register is restored by the action of popping the stack. If the operand-size attribute is 16, the words on the stack are transferred to the registers in the following order: DI, SI, BP, ignore word, BX, DX, CX, and AX.

Figure 7-2. Operation of the PUSHA Instruction

Figure 7-3. Operation of the POP Instruction Stack 31 0

Before Pushing Registers Growth

n - 4 ESP n - 8 n

Stack

0 31

After Pushing Registers

ESP EAX

EDI EBX

EBP ECX EDX

Old ESP

ESI n - 36

n - 20

n - 28 n - 12 n - 16

n - 24

n - 32

0

Stack 31After Popping Doubleword

Growth

n - 4 ESP n - 8 n

Stack Before Popping Doubleword

Doubleword Value ESP 0 31

Vol. 1 7-9 PROGRAMMING WITH GENERAL-PURPOSE INSTRUCTIONS

7.3.1.5 Stack Manipulation Instructions in 64-Bit Mode

In 64-bit mode, the stack pointer size is 64 bits and cannot be overridden by an instruction prefix.

In implicit stack references, address-size overrides are ignored. Pushes and pops of 32-bit values on the stack are not possible in 64-bit mode. 16-bit pushes and pops are supported by using the 66H operand-size prefix. PUSHA, PUSHAD, POPA, and POPAD are not supported.

7.3.1.6 Type Conversion Instructions

The type conversion instructions convert bytes into words, words into doublewords, and double-words into quaddouble-words. These instructions are especially useful for converting integers to larger integer formats, because they perform sign extension (see Figure 7-5).

Two kinds of type conversion instructions are provided: simple conversion and move and convert.

Figure 7-4. Operation of the POPA Instruction

Figure 7-5. Sign Extension Stack

After Popping Registers

Growth n - 4 ESP n - 8 n

Stack Before Popping Registers

ESP EAX

EDI EBX

EBP ECX EDX

Ignored

ESI n - 36

n - 20

n - 28 n - 12 n - 16

n - 24

n - 32

0 31

0 31

31

After Sign

15 0

S N N N N N N N N NNNN N N N S

S S S S S S S S S S S S S S

S Extension

Before Sign

15 0

S N N N N N N N N NNNN N N N Extension

7-10 Vol. 1

PROGRAMMING WITH GENERAL-PURPOSE INSTRUCTIONS

Simple conversion — The CBW (convert byte to word), CWDE (convert word to doubleword extended), CWD (convert word to doubleword), and CDQ (convert doubleword to quadword) instructions perform sign extension to double the size of the source operand.

The CBW instruction copies the sign (bit 7) of the byte in the AL register into every bit position of the upper byte of the AX register. The CWDE instruction copies the sign (bit 15) of the word in the AX register into every bit position of the high word of the EAX register.

The CWD instruction copies the sign (bit 15) of the word in the AX register into every bit posi-tion in the DX register. The CDQ instrucposi-tion copies the sign (bit 31) of the doubleword in the EAX register into every bit position in the EDX register. The CWD instruction can be used to produce a doubleword dividend from a word before a word division, and the CDQ instruction can be used to produce a quadword dividend from a doubleword before doubleword division.

Move with sign or zero extension — The MOVSX (move with sign extension) and MOVZX (move with zero extension) instructions move the source operand into a register then perform the sign extension.

The MOVSX instruction extends an 8-bit value to a 16-bit value or an 8-bit or 16-bit value to a 32-bit value by sign extending the source operand, as shown in Figure 7-5. The MOVZX instruction extends an 8-bit value to a 16-bit value or an 8-bit or 16-bit value to a 32-bit value by zero extending the source operand.

7.3.1.7 Type Conversion Instructions in 64-Bit Mode

The MOVSXD instruction operates on 64-bit data. It sign-extends a 32-bit value to 64 bits. This instruction is not encodable in non-64-bit modes.