PUSH Command
Description
Decrements the stack pointer and then stores the source operand on the top of the stack.
The address-size attribute of the stack segment determines the stack pointer
size (16 bits or 32 bits), and the operand-size attribute of the current code
segment determines the amount the stack pointer is decremented (2 bytes or 4
bytes). For example, if these address- and operand-size attributes are 32, the
32-bit ESP register (stack pointer) is decremented by 4 and, if they are 16, the
16-bit SP register is decremented 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
source operand.) Pushing a 16-bit operand when the stack address-size attribute
is 32 can result in a misaligned the stack pointer (that is, the stack pointer
is not aligned on a doubleword boundary).
The PUSH ESP instruction pushes the value of the ESP register as it existed
before the instruction was executed. Thus, if a PUSH instruction uses a memory
operand in which the ESP register is used as a base register for computing the
operand address, the effective address of the operand is computed before the ESP
register is decremented. In the real-address mode, if the ESP or SP register is
1 when the PUSH instruction is executed, the processor shuts down due to a lack
of stack space. No exception is generated to indicate this condition.
Intel Architecture Compatibility
For Intel Architecture processors from the Intel 286 on, the PUSH ESP instruction
pushes the value of the ESP register as it existed before the instruction was
executed. (This is also true in the real-address and virtual-8086 modes.) For
the Intel 8086 processor, the PUSH SP instruction pushes the new value of the SP
register (that is the value after it has been decremented by 2).
Below, there is a pseudo code fragment to demonstrate how the CPU behaves
upon the execution of a PUSH command:
IF StackAddrSize = 32 THEN
IF OperandSize = 32 THEN
ESP -> ESP - 4;
SS:ESP -> SRC; /* push doubleword */
ELSE /* OperandSize = 16*/
ESP -> ESP - 2;
SS:ESP -> SRC; /* push word */
FI;
ELSE /* StackAddrSize = 16*/
IF OperandSize = 16 THEN
SP -> SP - 2;
SS:SP -> SRC; /* push word */
ELSE /* OperandSize = 32*/
SP -> SP - 4;
SS:SP -> SRC; /* push doubleword */
FI;
FI;
Return