汇编:静态/全局变量的位置

时间:2019-08-06 05:01:44

标签: assembly x86-64

我有一个简单的C代码:

#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;
}

我得到了objdump,下面是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    

现在,我可以将此汇编代码与C代码相关联(即,我在理解逻辑上没有任何困难)。我也知道静态/全局变量存储在数据部分而不是堆栈中(如果我在这里错了,请更正我)。但是,我不明白为什么地址算法(与rpi有关的偏移量)每次都不相同。例如考虑以下两个说明:

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

这两个都对应于与指针p相关的操作。现在,我的问题是为什么两种情况下的地址都不同: 即rip+0x200b22rip+0x200b1b,它们都正在访问指针p(我相信p的静态位置是601040)?

1 个答案:

答案 0 :(得分:1)

RIP是指令指针。 (R = 64位寄存器名称)。

这两个指令位于不同的地址,因此它们与BSS变量的距离不同。 x86-64倾向于使用RIP相对寻址进行静态存储。 objdump向您展示了RIP相对寻址模式,并将其解码为# 601040 <p>的最终绝对地址

({ps应该在BSS中,因为它们没有非零的静态初始值设定项。但是,是的,静态存储。)

相关: