PUSH decrements the stack pointer (SP or ESP) by 2 or 4,
and then stores the given value at [SS:SP] or [SS:ESP].
The address-size attribute of the instruction determines whether
SP or ESP is used as the stack pointer: to deliberately
override the default given by the BITS setting, you can use an
a16 or a32 prefix.
The operand-size attribute of the instruction determines whether the
stack pointer is decremented by 2 or 4: this means that segment
register pushes in BITS 32 mode will push 4 bytes on the stack,
of which the upper two are undefined. If you need to override that,
you can use an o16 or o32 prefix.
The above opcode listings give two forms for general-purpose
register push instructions: for example, PUSH BX has the two
forms 53 and FF F3. NASM will always generate the shorter
form when given PUSH BX. NDISASM will disassemble both.
Unlike the undocumented and barely supported POP CS, PUSH CS
is a perfectly valid and sensible instruction, supported on all
processors.
The instruction PUSH SP may be used to distinguish an 8086 from
later processors: on an 8086, the value of SP stored is the
value it has after the push instruction, whereas on later
processors it is the value before the push instruction.