作者:手机用户2502862657 | 来源:互联网 | 2023-02-11 23:52
关于以下小代码,这在另一篇文章中有关结构大小和正确对齐数据的所有可能性的说明:
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 :
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: c6 05 00 00 00 00 01 movb $0x1,0x0(%rip) # b
b: 66 c7 05 00 00 00 00 movw $0x2,0x0(%rip) # 14
12: 02 00
14: c7 05 00 00 00 00 03 movl $0x3,0x0(%rip) # 1e
1b: 00 00 00
1e: c6 05 00 00 00 00 04 movb $0x4,0x0(%rip) # 25
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> 小智..:
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
说明符号名称/拆卸时重定位。当您将此对象链接到可执行文件时,它们将由链接器填充。
访问相对于`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
实际上,它们将在链接时填充;看起来OP分解了一个.o而不是一个链接的可执行文件。位置无关的代码不需要在每次加载时进行运行时修复。这是RIP相对寻址的一大优势。