What is the difference between mov and movabs?
Regular mov can only carry a 32-bit (sign-extended) immediate; movabs is the special form that loads a full 64-bit immediate constant.
x86-64 instructions keep their encodings short by limiting embedded immediates to 32 bits. Most constants fit (the signed range is roughly ±2 billion), so plain mov usually suffices:
movq $0x12345678, %rax # OK — fits in 32-bit signed
movq $0x123456789ABCDEF0, %rax # ERROR — immediate too large
movabs $0x123456789ABCDEF0, %rax # OK — movabs takes a 64-bit immediate
Why the limit exists: allowing 64-bit immediates everywhere would make every instruction much longer, hurting code density and cache use — so the architecture provides movabs only where you genuinely need a big constant.
When you reach for movabs: large addresses (above 2 GB in virtual memory), large numeric constants, or specific high-bit patterns. An alternative is to place the constant in .rodata and load it RIP-relative:
big_const: .quad 0x123456789ABCDEF0
movq big_const(%rip), %rax
Go deeper:
Felix Cloutier — MOV — the MOV operand encodings behind the 32-bit-immediate limit.