POP

Pop a Value from the Stack

Opcodes

Hex Mnemonic Encoding Long Mode Legacy Mode Description
0F A9 POP GS C N.E. Valid Pop top of stack into GS; increment stack pointer by 32 bits.
0F A9 POP GS C Valid Valid Pop top of stack into GS; increment stack pointer by 16 bits.
0F A1 POP FS C Valid N.E. Pop top of stack into FS; increment stack pointer by 64 bits.
0F A1 POP FS C N.E. Valid Pop top of stack into FS; increment stack pointer by 32 bits.
0F A1 POP FS C Valid Valid Pop top of stack into FS; increment stack pointer by 16 bits.
17 POP SS C Invalid Valid Pop top of stack into SS; increment stack pointer.
07 POP ES C Invalid Valid Pop top of stack into ES; increment stack pointer.
1F POP DS C Invalid Valid Pop top of stack into DS; increment stack pointer.
58+ rd POP r64 B Valid N.E. Pop top of stack into r64; increment stack pointer. Cannot encode 32-bit operand size.
58+ rd POP r32 B N.E. Valid Pop top of stack into r32; increment stack pointer.
58+ rw POP r16 B Valid Valid Pop top of stack into r16; increment stack pointer.
8F /0 POP r/m64 A Valid N.E. Pop top of stack into m64; increment stack pointer. Cannot encode 32-bit operand size.
8F /0 POP r/m32 A N.E. Valid Pop top of stack into m32; increment stack pointer.
8F /0 POP r/m16 A Valid Valid Pop top of stack into m16; increment stack pointer.

Instruction Operand Encoding

Op/En Operand 0 Operand 1 Operand 2 Operand 3
A NA NA NA ModRM:r/m (w)
B NA NA NA reg (w)
C NA NA NA NA

Description

Loads the value from the top of the stack to the location specified with the destination operand (or explicit opcode) and then increments the stack pointer. The destination operand can be a general-purpose register, memory location, or segment register.

The address-size attribute of the stack segment determines the stack pointer size (16, 32, 64 bits) and the operand-size attribute of the current code segment determines the amount the stack pointer is incremented (2, 4, 8 bytes).

For example, if the address- and operand-size attributes are 32, the 32-bit ESP register (stack pointer) is incremented by 4; if they are 16, the 16-bit SP register is incremented by 2. (The B flag in the stack segment's segment descriptor determines the stack's address-size attribute, and the D flag in the current code segment's segment descriptor, along with prefixes, determines the operand-size attribute and also the address-size attribute of the destination operand.)

If the destination operand is one of the segment registers DS, ES, FS, GS, or SS, the value loaded into the register must be a valid segment selector. In protected mode, popping a segment selector into a segment register automatically causes the descriptor information associated with that segment selector to be loaded into the hidden (shadow) part of the segment register and causes the selector and the descriptor information to be validated (see the "Operation" section below).

A NULL value (0000-0003) may be popped into the DS, ES, FS, or GS register without causing a general protection fault. However, any subsequent attempt to reference a segment whose corresponding segment register is loaded with a NULL value causes a general protection exception (#GP). In this situation, no memory reference occurs and the saved value of the segment register is NULL.

The POP instruction cannot pop a value into the CS register. To load the CS register from the stack, use the RET instruction.

If the ESP register is used as a base register for addressing a destination operand in memory, the POP instruction computes the effective address of the operand after it increments the ESP register. For the case of a 16-bit stack where ESP wraps to 0H as a result of the POP instruction, the resulting location of the memory write is processor-family-specific.

The POP ESP instruction increments the stack pointer (ESP) before data at the old top of stack is written into the destination.

A POP SS instruction inhibits all interrupts, including the NMI interrupt, until after execution of the next instruction. This action allows sequential execution of POP SS and MOV ESP, EBP instructions without the danger of having an invalid stack during an interrupt1. However, use of the LSS instruction is the preferred method of loading the SS and ESP registers.

In 64-bit mode, using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). When in 64-bit mode, POPs using 32-bit operands are not encodable and POPs to DS, ES, SS are not valid. See the summary chart at the beginning of this section for encoding data and limits.

Pseudo Code

IF StackAddrSize = 32
	IF OperandSize = 32
		DEST = SS:ESP; (* Copy a doubleword *)
		ESP = ESP + 4;
	ELSE
		(* OperandSize = 16 *)
		DEST = SS:ESP; (* Copy a word *)
		ESP = ESP + 2;
	FI;
ELSE
	IF StackAddrSize = 64
		IF OperandSize = 64
			DEST = SS:RSP; (* Copy quadword *)
			RSP = RSP + 8;
			1. If a code instruction breakpoint (for debug) is placed on an instruction located immediately after a POP SS instruction, the breakpoint may not be triggered. However, in a sequence of instructions that POP the SS register, only the first instruction in the sequence is guaranteed to delay an interrupt.
			In the following sequence, interrupts may be recognized before POP ESP executes:
				POP SS
				POP SS
				POP ESP
		ELSE
			(* OperandSize = 16 *)
			DEST = SS:RSP; (* Copy a word *)
			RSP = RSP + 2;
		FI;
	FI;
ELSE
	StackAddrSize = 16
	IF OperandSize = 16
		DEST = SS:SP; (* Copy a word *)
		SP = SP + 2;
	ELSE
		(* OperandSize = 32 *)
		DEST = SS:SP; (* Copy a doubleword *)
		SP = SP + 4;
	FI;
FI;
(* Loading a segment register while in protected mode results in special actions, as described in the following listing. These checks are performed on the segment selector and the segment descriptor it points to. *)
(* 64-BIT_MODE *)
IF FS, or GS is loaded with non-NULL selector;
	IF segment selector index is outside descriptor table limits OR segment is not a data or readable code segment OR ((segment is a data or nonconforming code segment) AND (both RPL and CPL > DPL))
		#GP(selector);
		IF segment not marked present
			#NP(selector);
		ELSE
			SegmentRegister = segment selector;
			SegmentRegister = segment descriptor;
		FI;
	FI;
	IF FS, or GS is loaded with a NULL selector;
		SegmentRegister = segment selector;
		SegmentRegister = segment descriptor;
	FI;
	(* PROTECTED MODE OR COMPATIBILITY MODE *)
	IF SS is loaded;
		IF segment selector is NULL
			#GP(0);
		FI;
		IF segment selector index is outside descriptor table limits
			or segment selector's RPL != CPL or segment is not a writable data segment or DPL != CPL
			#GP(selector);
		FI;
		IF segment not marked present
			#SS(selector);
		ELSE
			SS = segment selector;
			SS = segment descriptor;
		FI;
	FI;
	IF DS, ES, FS, or GS is loaded with non-NULL selector;
		IF segment selector index is outside descriptor table limits or segment is not a data or readable code segment or ((segment is a data or nonconforming code segment) and (both RPL and CPL > DPL))
			#GP(selector);
		FI;
		IF segment not marked present
			#NP(selector);
		FI;
	ELSE
		SegmentRegister = segment selector;
		SegmentRegister = segment descriptor;
	FI;
FI;
IF DS, ES, FS, or GS is loaded with a NULL selector
	SegmentRegister = segment selector;
	SegmentRegister = segment descriptor;
FI;

Flags Affected

None.

Exceptions

64-Bit Mode Exceptions

Exception Description
#UD If the LOCK prefix is used.
#NP If the FS or GS register is being loaded and the segment pointed to is marked not present.
#PF(fault-code) If a page fault occurs.
#AC(0) If an unaligned memory reference is made while alignment checking is enabled.
#GP(selector) If the descriptor is outside the descriptor table limit. If the FS or GS register is being loaded and the segment pointed to is not a data or readable code segment. If the FS or GS register is being loaded and the segment pointed to is a data or nonconforming code segment, but both the RPL and the CPL are greater than the DPL.
#SS(U) If the stack address is in a non-canonical form.
#GP(0) If the memory address is in a non-canonical form.

Compatibility Mode Exceptions

Same as for protected mode exceptions.

Virtual-8086 Mode Exceptions

Exception Description
#UD If the LOCK prefix is used.
#AC(0) If an unaligned memory reference is made while alignment checking is enabled.
#PF(fault-code) If a page fault occurs.
#GP(0) If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.

Real-Address Mode Exceptions

Exception Description
#UD If the LOCK prefix is used.
#GP If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.

Protected Mode Exceptions

Exception Description
#UD If the LOCK prefix is used.
#AC(0) If an unaligned memory reference is made while the current privilege level is 3 and alignment checking is enabled.
#PF(fault-code) If a page fault occurs.
#NP If the DS, ES, FS, or GS register is being loaded and the segment pointed to is marked not present.
#SS(selector) If the SS register is being loaded and the segment pointed to is marked not present.
#SS(0) If the current top of stack is not within the stack segment. If a memory operand effective address is outside the SS segment limit.
#GP(selector) If segment selector index is outside descriptor table limits. If the SS register is being loaded and the segment selector's RPL and the segment descriptor's DPL are not equal to the CPL. If the SS register is being loaded and the segment pointed to is a non-writable data segment. If the DS, ES, FS, or GS register is being loaded and the segment pointed to is not a data or readable code segment. If the DS, ES, FS, or GS register is being loaded and the segment pointed to is a data or nonconforming code segment, but both the RPL and the CPL are greater than the DPL.
#GP(0) If attempt is made to load SS register with NULL segment selector. If the destination operand is in a non-writable segment. If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit. If the DS, ES, FS, or GS register is used to access memory and it contains a NULL segment selector.