如何解释x86-64上的段寄存器访问?

时间:2011-10-21 04:25:49

标签: linux assembly x86 x86-64

使用此功能:

mov    1069833(%rip),%rax        # 0x2b5c1bf9ef90 <_fini+3250648>
add    %fs:0x0,%rax
retq

如何解释第二条指令并找出添加到RAX的内容?

2 个答案:

答案 0 :(得分:8)

此代码:

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。

答案 1 :(得分:3)

我不确定它们是否已被称为 segment 注册,因为分段架构已经过去了。我认为正确的术语是选择器(但我可能是错的)。

但是,我认为您只需要fs区域的第一个四字(64位)。

%fs:0x0位表示fs:0处内存的内容。由于您使用了通用add(而不是addl),我认为它将从目标%rax获取数据宽度。

就获得实际价值而言,这取决于您是处于遗留模式还是长模式。

在传统模式下,您必须获取fs值并在GDT(或可能是LDT)中查找以获取基址。

在长模式下,您需要查看相关的模型特定寄存器。如果你在这一点上,不幸的是你已经超出了我的专业水平。