了解英特尔汇编中的 %rip 寄存器
Understanding %rip register in intel assembly
关于以下小代码,在另一个 post 中说明了结构的大小和正确对齐数据的所有可能性:
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 [=11=]x1,0x0(%rip) # b <fun+0xb>
b: 66 c7 05 00 00 00 00 movw [=11=]x2,0x0(%rip) # 14 <fun+0x14>
12: 02 00
14: c7 05 00 00 00 00 03 movl [=11=]x3,0x0(%rip) # 1e <fun+0x1e>
1b: 00 00 00
1e: c6 05 00 00 00 00 04 movb [=11=]x4,0x0(%rip) # 25 <fun+0x25>
25: b8 0c 00 00 00 mov [=11=]xc,%eax
2a: 5d pop %rbp
2b: c3 retq
我不知道如何计算位于右侧的条款,似乎是使用的address of local variables
。而且,我不知道用%rip register
来计算
你能举个例子说明 %rip
和 %rsp
或 %rbp
之间的 link 吗,特别是在我使用 [=17 时的地址计算中=] 说明。
RIP 寻址总是相对于 RIP(64 位指令指针)寄存器。所以它只能用于全局变量。 0 偏移量等于 RIP 寻址指令之后的后续指令的地址。例如:
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
显示符号名称/重定位。当您 link 将此对象转换为可执行文件时,它们将由 linker 填充。
访问相对于 `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
关于以下小代码,在另一个 post 中说明了结构的大小和正确对齐数据的所有可能性:
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 [=11=]x1,0x0(%rip) # b <fun+0xb>
b: 66 c7 05 00 00 00 00 movw [=11=]x2,0x0(%rip) # 14 <fun+0x14>
12: 02 00
14: c7 05 00 00 00 00 03 movl [=11=]x3,0x0(%rip) # 1e <fun+0x1e>
1b: 00 00 00
1e: c6 05 00 00 00 00 04 movb [=11=]x4,0x0(%rip) # 25 <fun+0x25>
25: b8 0c 00 00 00 mov [=11=]xc,%eax
2a: 5d pop %rbp
2b: c3 retq
我不知道如何计算位于右侧的条款,似乎是使用的address of local variables
。而且,我不知道用%rip register
你能举个例子说明 %rip
和 %rsp
或 %rbp
之间的 link 吗,特别是在我使用 [=17 时的地址计算中=] 说明。
RIP 寻址总是相对于 RIP(64 位指令指针)寄存器。所以它只能用于全局变量。 0 偏移量等于 RIP 寻址指令之后的后续指令的地址。例如:
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
显示符号名称/重定位。当您 link 将此对象转换为可执行文件时,它们将由 linker 填充。
访问相对于 `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