0

I have a simple c code:

#include <stdlib.h> static int x = 4; static int *p; int *s; struct B { int *s; int j; }; void foo() { static int *pointer; static struct B *c; c = malloc(sizeof(struct B)); x = 5; p = &x; p = s; pointer = p; static struct B b; b.s = &x; b.j = 9; } int main(int argc, char *argv[]) { static char buf[10] = ""; static char b; x = 5; /* OK */ buf[9] = 'A'; b = 'C'; return 0; } 

I get the objdump of this and following is the foo function:

00000000004004e6 <foo>: 4004e6: 55 push rbp 4004e7: 48 89 e5 mov rbp,rsp 4004ea: bf 10 00 00 00 mov edi,0x10 4004ef: e8 fc fe ff ff call 4003f0 <malloc@plt> 4004f4: 48 89 05 4d 0b 20 00 mov QWORD PTR [rip+0x200b4d],rax # 601048 <c.2532> 4004fb: c7 05 1f 0b 20 00 05 mov DWORD PTR [rip+0x200b1f],0x5 # 601024 <x> 400502: 00 00 00 400505: 48 c7 05 30 0b 20 00 mov QWORD PTR [rip+0x200b30],0x601024 # 601040 <p> 40050c: 24 10 60 00 400510: 48 8b 05 69 0b 20 00 mov rax,QWORD PTR [rip+0x200b69] # 601080 <s> 400517: 48 89 05 22 0b 20 00 mov QWORD PTR [rip+0x200b22],rax # 601040 <p> 40051e: 48 8b 05 1b 0b 20 00 mov rax,QWORD PTR [rip+0x200b1b] # 601040 <p> 400525: 48 89 05 24 0b 20 00 mov QWORD PTR [rip+0x200b24],rax # 601050 <pointer.253 1> 40052c: 48 c7 05 29 0b 20 00 mov QWORD PTR [rip+0x200b29],0x601024 # 601060 <b.2533 > 400533: 24 10 60 00 400537: c7 05 27 0b 20 00 09 mov DWORD PTR [rip+0x200b27],0x9 # 601068 <b.2533+0x8> 40053e: 00 00 00 400541: 90 nop 400542: 5d pop rbp 400543: c3 ret 

Now, I can relate this assembly code with c code (i.e. I didn't have any difficulties understanding the logic). I also know that the static/ global variables are stored in the data section and not on the stack (correct me if I'm wrong here). But, I don't get why the address arithmetic (offset related to rpi) is different every time. For e.g. consider these two instructions:

mov QWORD PTR [rip+0x200b22],rax # 601040 <p> mov rax,QWORD PTR [rip+0x200b1b] # 601040 <p> 

Both of these corresponds to the operation related to the pointer p. Now, my question is why the addresses are different in both of the cases: i.e. rip+0x200b22 and rip+0x200b1b yet, both of them are accessing the pointer p (I believe the static location of p is 601040)?

0

1 Answer 1

1

RIP is the instruction pointer. (R = 64-bit register name).

The two instructions are at different addresses so their distance to a BSS variable is different. x86-64 prefers RIP-relative addressing for static storage. objdump is showing you the RIP-relative addressing mode, and decoding it to the final absolute address as # 601040 <p>

(p and s should be in the BSS because they don't have a non-zero static initializer. But yes, static storage.)

Related:

Sign up to request clarification or add additional context in comments.

2 Comments

forgive my ignorance, but why doesn't rip + <value> add up to the pointer's location - for example, in the above case it adds up to 601039 and not 601040, also I observed the same in some different cases.
@Ruturaj: RIP-relative addressing is relative to the end of the instruction. 0x601039 + 7 = 0x601040 Or just look at the address of the next instruction to get the address of the current.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.