I have some gnu assembler code for the x86_64 architecture generated by a tool and there are these instructions:
movq %rsp, %rbp
leaq str(%rip), %rdi
callq puts
movl $0, %eax
I can not find actual documentation on the "callq" instruction.
I have looked at http://support.amd.com/TechDocs/24594.pdf which is "AMD64 Architecture Programmer’s Manual Volume 3: General-Purpose and System Instructions" but they only describe CALL near and far instructions.
I have looked at documentation for gnu assembler https://sourceware.org/binutils/docs/as/index.html but could not find the section detailing the instructions it supports.
I understand that its a call to a function, but I would like to know the details. Where can I find them?
callq refers to a relocatable call in shared libraries/dynamic libraries. The idea is push 0, then push the symbol of to search then call a function so search for it on the first call. In the relocatable table of the program, it replaces the call to the actual location of the function on the first call of the function. Subsequent calls refer to the relocation table that was created at run time.
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
andcallw
aren't encodeable in 64-bit mode, so it's just annoying that some AT&T syntax tools show it ascallq
instead ofcall
. This of course applies toretq
as well.Different tools are different in 32 vs. 64-bit mode. (Godbolt)
call
/ret
. Nice.callq
/retq
andcalll
/retl
. At least it's consistently annoying.objdump -d:
callq
/retq
(explicit 64-bit) andcall
/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 implicitlypushq
, even thoughpushw $1
andpushq $1
are both encodeable (and usable in practice) in 64-bit mode.From Intel's instruction-set ref manual (linked above):
In 32-bit mode, you can encode a 16-bit
call rel16
that truncates EIP to 16 bits, or acall r/m16
that uses an absolute 16-bit address. But as the manual says, the operand-size is fixed in 64-bit mode.