NASM returns an error like: "instruction not supported in 64-bit mode"
(Or with YASM, invalid size for operand 1)
The subject instructions are pop ecx and push ecx.
What can I use instead of them or is there an other way to fix this issue?
NASM returns an error like: "instruction not supported in 64-bit mode"
(Or with YASM, invalid size for operand 1)
The subject instructions are pop ecx and push ecx.
What can I use instead of them or is there an other way to fix this issue?
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. Does each PUSH instruction push a multiple of 8 bytes on x64? (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, 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, 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.
push ax) and memory references (push word ptr[rax]);push word 1238-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.