【问题标题】:assembly: position of static/ global variables程序集:静态/全局变量的位置
【发布时间】:2019-08-06 05:01:44
【问题描述】:

我有一个简单的 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)?

【问题讨论】:

    标签: assembly x86-64


    【解决方案1】:

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

    两条指令位于不同的地址,因此它们与 BSS 变量的距离不同。 x86-64 更喜欢静态存储的 RIP 相对寻址。 objdump 向您展示 RIP 相对寻址模式,并将其解码为最终的绝对地址为 # 601040 &lt;p&gt;

    ps 应该在 BSS 中,因为它们没有非零静态初始化器。但是,是的,静态存储。)

    相关:

    【讨论】:

    • 原谅我的无知,但是为什么不 rip + 加起来指针的位置 - 例如,在上面的情况下它加起来是 601039 而不是 601040,我也观察到了同样的情况在一些不同的情况下。
    • @Ruturaj:RIP 相对寻址是相对于指令的 end 而言的。 0x601039 + 7 = 0x601040或者直接看下一条指令的地址就可以得到当前的地址。
    猜你喜欢
    • 1970-01-01
    • 2015-06-12
    • 1970-01-01
    • 2022-01-28
    • 1970-01-01
    • 2022-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多