background image

Vol. 1 7-5

PROGRAMMING WITH GENERAL-PURPOSE INSTRUCTIONS

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 8, “Multiple-Processor Management,” 
of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A, 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 registers is stored in the destination 
operand. If the EDX:EAX registers and the destination are not equal, the destination is loaded in the EDX:EAX 
registers. The 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 functionality 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 procedure. 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 instructions 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

0

Stack

31

Before Pushing Doubleword

Growth

ESP

n

 − 4

− 8

n

Stack

0

31

After Pushing Doubleword

ESP

Doubleword Value