64-BIT mode does not support PUSH and POP instructions
The general idea is that you usually push and pad full registers, i.e. 64-bit registers in 64-bit mode. push
the default operand size is 64-bit, and 32-bit operand size is not available. Does each PUSH instruction do multiples of 8 bytes on x64? (yes, unless you specifically use 16-bit push, but 32-bit is not available).
You cannot push a 32-bit register in 64-bit mode; instead, you can push and put the entire 64 bit register that contains the 32 bit value you need to push rax
instead push eax
. The same is true for memory references - you can push qword ptr[rax]
, but not push dword ptr[rax]
.
But: even in 64 bit mode, you can still press:
-
8 or 32 bit signs sign extended to 64; this is usually handled by your assembler as an optimization (if you do
push 1
, it will encode it with the most compact encoding there will be6A01
, that is, with the operand imm8). It will always be a 64-bit push unless you explicitly specify itpush word 1
, no matter what width is immediately picked by the assembler. -
segment registers
fs
, andgs
, but not the registerscs
,ds
,es
,ss
(which is not important in 64-bit mode, and can be readmov
, but notpush
releasing the push / pop code for potential use in the future).As an exception, segment registers are either zero-extended or pushed onto the stack with a 16-bit move (that is, the remaining 48 bits in the stack remain unchanged); this is not a big problem as
pop fs
itpop gs
just throws those extra bits away.
You can emulate push imm64
with push low32
/ mov dword [rsp+4], high32
. Or with mov r64, imm64
/ push r64
; mov
for registration (not memory) is the only x86-64 instruction that can accept 64-bit immediate.
With a 16-bit operand size (prefix 66h
), you can do a 16-bit push that sets the RSP to 2 instead of 8. But usually don't do that because it will shift 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 extended character or 16-bit.
8-bit registers cannot be pressed in any mode (except as part of a wider register), and 32-bit is not available in 64-bit mode, with a prefixREX.W=0
.
source to share