了解英特尔汇编中的%rip寄存器

时间:2017-02-13 23:03:12

标签: assembly x86-64 intel mov

关于以下小代码,在另一篇文章中说明了结构的大小以及正确对齐数据的所有可能性:

struct
{
 char Data1;
 short Data2;
 int Data3;
 char Data4;
} x;

unsigned fun ( void )
{
    x.Data1=1;
    x.Data2=2;
    x.Data3=3;
    x.Data4=4;
    return(sizeof(x));
}

我得到相应的反汇编(64位)

0000000000000000 <fun>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   c6 05 00 00 00 00 01    movb   $0x1,0x0(%rip)        # b <fun+0xb>
   b:   66 c7 05 00 00 00 00    movw   $0x2,0x0(%rip)        # 14 <fun+0x14>
  12:   02 00 
  14:   c7 05 00 00 00 00 03    movl   $0x3,0x0(%rip)        # 1e <fun+0x1e>
  1b:   00 00 00 
  1e:   c6 05 00 00 00 00 04    movb   $0x4,0x0(%rip)        # 25 <fun+0x25>
  25:   b8 0c 00 00 00          mov    $0xc,%eax
  2a:   5d                      pop    %rbp
  2b:   c3                      retq   

我不知道如何计算右侧的术语,这些术语似乎是address of local variables使用的。此外,我不知道用%rip register

计算它

您能举例说明%rip%rsp%rbp之间的关联,特别是在我使用move指令时的地址计算中。

1 个答案:

答案 0 :(得分:4)

RIP寻址始终与RIP(64位指令指针)寄存器相关。所以它只能用于全局变量。在RIP寻址指令之后,0偏移量等于以下指令的地址。例如:

   mov  al,[rip+2]                     al=53
   jmp  short next   (length=2 bytes)   
db 53
next:
   mov  bl,[rip-7]   (length=6 bytes)  bl=53

您通常不会将数据与您的代码混合在一起,除非是立即数,但这表明如果您实际运行的代码具有非常小的偏移量会发生什么。

在您的代码中,您无法查看和检查偏移量(您看到四个零),因为您反汇编了.o。使用objdump -drwC在拆卸时显示符号名称/重定位。将此对象链接到可执行文件时,链接器将填充它们。

相对于`rbp:

访问本地的示例
push rbp      ;save rbp
mov rbp,rsp   ;rbp = pointer to return address (8 bytes)
sub rsp,64    ;reserve 64 bytes for local variables
mov rax,[rbp+8];  rax = the last stack-passed qword parameter (if any)
mov rdx,[rbp];    rdx = return address
mov rcx,[rbp-8];  rcx = first qword local variable (this is undefined now)
mov r8, [rbp-16];  r8  = second qword local variable (this is undefined now)
.
.
mov rsp,rbp
pop rbp
ret