Reputation: 353
I'm aware what the callq
instruction does; it is described in this answer. The instruction should have one parameter, which should be the address of the function called.
However, when disassembling an object file I see the following line showing a callq
instruction with two values instead of one parameter:
1e: e8 00 00 00 00 callq 23 <main+0x19>
I assume that 23
is the return address and <main+0x19>
is the address of the function to be called. However, the function which is called is not located at address main+0x19
.
What is the meaning of the two values 23
and main+0x19
shown in the disassembly of the callq
instruction?
Original C code:
#include <stdio.h>
void fun(int a)
{
}
int main()
{
int a = 1234;
fun(a);
}
objdump -D main.o main.asm Disassambly code:
0000000000000000 <fun>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 89 7d fc mov %edi,-0x4(%rbp)
7: 90 nop
8: 5d pop %rbp
9: c3 retq
000000000000000a <main>:
a: 55 push %rbp
b: 48 89 e5 mov %rsp,%rbp
e: 48 83 ec 10 sub $0x10,%rsp
12: c7 45 fc 03 00 00 00 movl $0x3,-0x4(%rbp)
19: 8b 45 fc mov -0x4(%rbp),%eax
1c: 89 c7 mov %eax,%edi
1e: e8 00 00 00 00 callq 23 <main+0x19>
23: b8 00 00 00 00 mov $0x0,%eax
28: c9 leaveq
29: c3 retq
Upvotes: 3
Views: 4252
Reputation: 12432
The callq instruction has only one operand, not two as implied in the question. The disassembler displays it in two forms, as an address and as a symbol + offset.
You are looking at disassembly of an unlinked object file. Since the file being disassembled isn't linked, the destination address shown isn't the address of fun
. The assembler puts 0 in the operand field of the instruction and creates a relocation record for the linker to fill in the offset to the final address of the destination.
The operand of the call instruction is an offset, relative to the address of the next instruction after the call. So a value of 0 in the operand field causes the disassembler to display the address of the next instruction as the destination of the call. In the disassembly shown, that is address 23.
If you make fun
a static function, the assembler may fill in the true offset of the function, since it won't require relocation, and you will see it in the disassembly. (This may depend on the exact tools and options you are using.)
If you disassemble a linked executable, the disassembler will show the true destination address of the call.
You can also use objdump -drwC
(optionally with -Mintel
) to show relocations as comments on instructions when disassembling a file like a .o
that has some placeholders with relocations.
Upvotes: 7