At a glance [and loosely] ...
You're using an x86 in 64 bit mode.
64 bit mode has a special addressing mode known as "RIP relative" addressing.
Edit: From Peter, the addressing mode is actually call rel32
, rather than RIP relative
, although the offset calculations will be the same.
The %rip
register is the program counter. It changes on each instruction.
So, when using this mode, the offset is how far away the target address (e.g. apples
) is from the address of the current instruction (from the address in %rip
for the instruction).
Since you have two callq
instructions (from your description, but not shown in the code), they each have a different address, so the offset to apples
will be different.
This allows for "position independent code". It also allows an offset to be used, which is usually smaller than a full 64 bit absolute address. That's why the callq
instruction (opcode + offset/address) is only 5 bytes (vs. 9 bytes) because the offset is a signed 32 bit quantity.
UPDATE:
I thought rip may be involved. In this particular instance, can you help me decipher how to find the rip% or kind of walk through this specific problem?
You could do: objdump --disassemble myprogram
to get a disassembly and look at the disassembly. Or, you could do this with the debugger (e.g. gdb
) using the disassemble
command.
From your listing, the address of the callq
is 0x400541 and [you mentioned that] apples
is at 0x4004ed.
So, the offset from the start of the callq
instruction is:
-84 FFFFFFFFFFFFFFAC
But, the instruction has an offset of:
0xFFFFFFFA7
(Remember that the disassembly just puts out the bytes, so we have to manually reverse the bytes because the offset is little-endian).
So, this means that the %rip
value used is not the start of the instruction, but, rather the end of the instruction.
So, we have to adjust the offset by the length of the instruction [which is 5] to get 0xFFFFFFA7. That is, the %rip
value [used by] the callq
instruction is the address of the instruction + 5. In pseudo code, the calculation is:
offset = apples - (&callq + 5)