Reputation: 1954
This simple hello world:
#include <stdio.h>
int main(void) {
printf("Hello, world!\n");
printf("Hello, world!\n");
return 0;
}
Gives the following assembly in objdump:
/helloworld.c:3 804842c: 83 ec 0c sub $0xc,%esp 804842f: 68 f0 84 04 08 push $0x80484f0 8048434: e8 b7 fe ff ff call 80482f0 8048439: 83 c4 10 add $0x10,%esp /helloworld.c:4 804843c: 83 ec 0c sub $0xc,%esp 804843f: 68 f0 84 04 08 push $0x80484f0 8048444: e8 a7 fe ff ff call 80482f0 8048449: 83 c4 10 add $0x10,%esp
Upvotes: 1
Views: 836
Reputation: 11438
The E8
opcode belongs to a CALL
instruction whose address is relative to the address of the CALL
instruction itself. It uses PC relative addressing
. So, what you see as the address of the function is actually the offset from the address of the next instruction to the address of the start of the printf
function.
By the way, Intel uses little endian, so those offsets must be read as signed 32-bit integers FFFFFEB7
and FFFEA7
respectively. That means that the printf
function is located in a lower address relative to your main program.
You can see also that the difference from these two offsets is the difference in bytes from one CALL
instruction to the other one, as the second CALL
will be farther from the beginning of printf
than the first one.
0x8048444 - 0x8048434 = 16 (decimal)
0xFFFFFEB7 - 0xFFFFFEA7 = 16 (decimal)
Upvotes: 2
Reputation: 8825
call rel32
instruction: Call near, displacement relative to next instruction
The opcode for this instruction is E8
, followed by the relative offset that is computed by the following equation: destination address - address of next instruction
.
In this case, the relative offset of the first call is 80482f0 - 8048439 = FFFFFEB7
, and the relative offset of the second call is 80482f0 - 8048449 = FFFFFEA7
.
Upvotes: 2