It's just call
. Use Intel-syntax disassembly if you want to be able to look up instructions in the Intel/AMD manuals.
The q
operand-size suffix does technically apply (it pushes a 64-bit return address and treats RIP as a 64-bit register), but there's no way to override it with instruction prefixes. i.e. calll
and callw
aren't encodeable in 64-bit mode, so it's just annoying that some AT&T syntax tools show it as callq
instead of call
. This of course applies to retq
as well.
Different tools are different in 32 vs. 64-bit mode. (Godbolt)
- gcc -S: always
call
/ret
. Nice.
- clang -S:
callq
/retq
and calll
/retl
. At least it's consistently annoying.
objdump -d: callq
/retq
(explicit 64-bit) and call
/ret
(implicit for 32-bit). Inconsistent and kinda dumb because 64-bit has no choice of operand-size, but 32-bit does. (Not a useful choice, though: callw
truncates EIP to 16 bits.)
Although on the other hand, the default operand size (without a REX.W prefix) for most instructions in 64-bit mode is still 32. But add $1, (%rdi)
needs an operand-size suffix; the assembler won't pick 32-bit for you if nothing implies one. OTOH, push
is implicitly pushq
, even though pushw $1
and pushq $1
are both encodeable (and usable in practice) in 64-bit mode.
From Intel's instruction-set ref manual (linked above):
For a near call absolute, an absolute offset is specified indirectly in a general-purpose register or a memory location (r/m16, r/m32, or r/m64).
The operand-size attribute determines the size of the target operand (16, 32 or 64 bits). When in 64-bit mode, the operand size for near call (and all near branches) is forced to 64-bits.
for rel32 ... As with absolute offsets, the operand-size attribute determines the size of the target operand (16, 32, or 64 bits). In 64-bit mode the target operand will always be 64-bits because the operand size is forced to 64-bits for near branches.
In 32-bit mode, you can encode a 16-bit call rel16
that truncates EIP to 16 bits, or a call r/m16
that uses an absolute 16-bit address. But as the manual says, the operand-size is fixed in 64-bit mode.
callq
specifically. And there is actually non-obvious stuff to say about default operand-sizes for branches and other stack instructions. This is a newbie question, but actually one that's worth answering for a change, if I stop being grumpy with all the bad "my code doesn't work and I don't know anything" questions. – Peter Cordes