【发布时间】:2011-12-12 07:08:39
【问题描述】:
使用此功能:
mov 1069833(%rip),%rax # 0x2b5c1bf9ef90 <_fini+3250648>
add %fs:0x0,%rax
retq
如何解释第二条指令并找出添加到 RAX 的内容?
【问题讨论】:
-
假设您在 linux 下运行,this 问题可能是相关的。
使用此功能:
mov 1069833(%rip),%rax # 0x2b5c1bf9ef90 <_fini+3250648>
add %fs:0x0,%rax
retq
如何解释第二条指令并找出添加到 RAX 的内容?
【问题讨论】:
我不确定自从分段架构的糟糕旧时代以来它们是否被称为 segment register。我相信正确的术语是选择器(但我可能是错的)。
但是,我认为您只需要在fs 区域中的第一个四字(64 位)。
%fs:0x0 位表示fs:0 处的内存内容。由于您使用了通用 add(而不是 addl 例如),我认为它将从目标 %rax 获取数据宽度。
就获得实际价值而言,这取决于您是处于 legacy 模式还是 long 模式。
在旧模式下,您必须获取 fs 值并在 GDT(或可能是 LDT)中查找它才能获取基地址。
在长模式下,您需要查看相关模型特定的寄存器。如果您处于这一点,那么不幸的是,您已经超出了我的专业水平。
【讨论】:
这段代码:
mov 1069833(%rip),%rax # 0x2b5c1bf9ef90 <_fini+3250648>
add %fs:0x0,%rax
retq
正在返回线程局部变量的地址。 %fs:0x0 是 TCB(线程控制块)的地址,1069833(%rip) 是从那里到变量的偏移量,这是已知的,因为变量驻留在程序中或在程序加载时加载的某个动态库中(在运行时通过dlopen() 加载的库需要一些不同的代码)。
Ulrich Drepper 的 TLS document 对此进行了详细解释,特别是 §4.3 和 §4.3.6。
【讨论】: