Intel 64 and IA-32 Architectures Software Developers Manual Volume 1, Basic Architecture

Vol. 1 6-3
PROCEDURE CALLS, INTERRUPTS, AND EXCEPTIONS
3. Load the stack pointer for the stack into the ESP register using a MOV, POP, or
LSS instruction. The LSS instruction can be used to load the SS and ESP registers
in one operation.
See “Segment Descriptors” in of the Intel® 64 and IA-32 Architectures Software
Developer’s Manual, Volume 3A, for information on how to set up a segment
descriptor and segment limits for a stack segment.
6.2.2 Stack Alignment
The stack pointer for a stack segment should be aligned on 16-bit (word) or 32-bit
(double-word) boundaries, depending on the width of the stack segment. The D flag
in the segment descriptor for the current code segment sets the stack-segment width
(see “Segment Descriptors” in Chapter 3, “Protected-Mode Memory Management,” of
the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A).
The PUSH and POP instructions use the D flag to determine how much to decrement
or increment the stack pointer on a push or pop operation, respectively. When the
stack width is 16 bits, the stack pointer is incremented or decremented in 16-bit in-
crements; when the width is 32 bits, the stack pointer is incremented or decremented
in 32-bit increments. Pushing a 16-bit value onto a 32-bit wide stack can result in
stack misaligned (that is, the stack pointer is not aligned on a doubleword boundary).
One exception to this rule is when the contents of a segment register (a 16-bit seg-
ment selector) are pushed onto a 32-bit wide stack. Here, the processor automatical-
ly aligns the stack pointer to the next 32-bit boundary.
The processor does not check stack pointer alignment. It is the responsibility of the
programs, tasks, and system procedures running on the processor to maintain prop-
er alignment of stack pointers. Misaligning a stack pointer can cause serious perfor-
mance degradation and in some instances program failures.
6.2.3 Address-Size Attributes for Stack Accesses
Instructions that use the stack implicitly (such as the PUSH and POP instructions)
have two address-size attributes each of either 16 or 32 bits. This is because they
always have the implicit address of the top of the stack, and they may also have an
explicit memory address (for example, PUSH Array1[EBX]). The attribute of the
explicit address is determined by the D flag of the current code segment and the
presence or absence of the 67H address-size prefix.
The address-size attribute of the top of the stack determines whether SP or ESP is
used for the stack access. Stack operations with an address-size attribute of 16 use
the 16-bit SP stack pointer register and can use a maximum stack address of FFFFH;
stack operations with an address-size attribute of 32 bits use the 32-bit ESP register
and can use a maximum address of FFFFFFFFH. The default address-size attribute for
data segments used as stacks is controlled by the B flag of the segments descriptor.
When this flag is clear, the default address-size attribute is 16; when the flag is set,
the address-size attribute is 32.