*The general idea* is that you normally push and pop full registers, i.e. 64-bit registers in 64-bit mode. `push`'s default operand-size is 64-bit, and 32-bit operand-size is not available.
[To see links please register here]
(yes, unless you specifically use a 16-bit push, but 32-bit isn't available).
You cannot push a 32 bit register in 64 bit mode; instead, you can push and pop the whole 64 bit register that contains a 32-bit value you want, so that's `push rax` instead of `push eax`. The same holds for memory references - you can `push qword ptr[rax]`, but not `push dword ptr[rax]`.
*But*: even in 64 bit mode you can still push:
- 8 or 32 bit immediates sign extended to 64; this is generally handled automatically by your assembler as an optimization (if you do `push 1` it will encode it with the most compact encoding, which will be `6A01`, i.e. with an *imm8* operand). It's [always a 64-bit push unless you explicitly specify `push word 1`][1], regardless of what width of immediate the assembler picks.
- the `fs` and `gs` segment registers *but not* the `cs`, `ds`, `es`, `ss` registers (which aren't important in 64-bit mode, and can only be read with [`mov`][2], not `push`, freeing up those push/pop opcode for potential future use).
As an exception, segment registers are either *zero*-extended or pushed on the stack with a 16-bit move (i.e. the other 48 bit on the stack are left unmodified); this isn't really much of a problem, since `pop fs` and `pop gs` just discard these extra bits.
You can emulate a `push imm64` with `push low32` / `mov dword [rsp+4], high32`. Or with `mov r64, imm64` / `push r64`; `mov` to register (not memory) is the only x86-64 instruction that can take a 64-bit immediate.
----
With 16-bit operand-size (a `66h` prefix), you can do a 16-bit push which adjusts RSP by 2 instead of 8. But normally don't do this because it will misalign the stack until you do a 16-bit pop or otherwise correct it.
- 16 bit registers (`push ax`) and memory references (`push word ptr[rax]`);
- 8-bit sign-extended or 16 bit immediates. `push word 123`
----
8-bit registers can't be pushed in any mode (except as part of a wider register), and 32-bit push/pop aren't available in 64-bit mode, [even with a `REX.W=0` prefix][1].
[1]:
[To see links please register here]
[2]:
[To see links please register here]