Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is callq instruction?

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?

like image 959
user10607 Avatar asked Oct 15 '17 08:10

user10607


People also ask

What does Callq mean?

The instruction callq *(%rax) loads a quad word (64 bits) from the address stored in rax and calls the function beginning at that quad word. Refer to the GNU assembler manual for details on the syntax.

What is the rip register?

The %rip register on x86-64 is a special-purpose register that always holds the memory address of the next instruction to execute in the program's code segment.

What does Movl instruction do?

movl var, %eax. Move the contents of memory location var into number register %eax.

How does CMP work Assembly?

The CMP instruction compares two operands. It is generally used in conditional execution. This instruction basically subtracts one operand from the other for comparing whether the operands are equal or not. It does not disturb the destination or source operands.


Video Answer


1 Answers

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.

like image 148
Peter Cordes Avatar answered Sep 28 '22 03:09

Peter Cordes