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

时间:2021-08-10 15:12:15

With this function:

有了这个功能:

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

How do I interpret the second instruction and find out what was added to RAX?

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

2 个解决方案

#1


8  

This code:

这段代码:

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

is returning the address of a thread-local variable. %fs:0x0 is the address of the TCB (Thread Control Block), and 1069833(%rip) is the offset from there to the variable, which is known since the variable resides either in the program or on some dynamic library loaded at program's load time (libraries loaded at runtime via dlopen() need some different code).

返回一个线程局部变量的地址。 %fs:0x0是TCB(线程控制块)的地址,1069833(%rip)是从那里到变量的偏移量,这是已知的,因为变量驻留在程序中或程序中加载的某个动态库上加载时间(通过dlopen()在运行时加载的库需要一些不同的代码)。

This is explained in great detail in Ulrich Drepper's TLS document, specially §4.3 and §4.3.6.

这在Ulrich Drepper的TLS文档中有详细解释,特别是§4.3和§4.3.6。

#2


3  

I'm not sure they've been called segment register since the bad old days of segmented architecture. I believe the proper term is a selector (but I could be wrong).

我不确定他们自从分段架构的旧时代以来就被称为段寄存器。我相信正确的术语是选择器(但我可能是错的)。

However, I think you just need at the first quadword (64 bits) in the fs area.

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

The %fs:0x0 bit means the contents of the memory at fs:0. Since you've used the generic add (rather than addl for example), I think it will take the data width from the target %rax.

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

In terms of getting the actual value, it depends on whether you're in legacy or long mode.

在获取实际值方面,这取决于您是处于遗留模式还是长模式。

In legacy mode, you'll have to get the fs value and look it up in the GDT (or possibly LDT) in order to get the base address.

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

In long mode, you'll need to look at the relevant model specific registers. If you're at this point, you've moved beyond my level of expertise unfortunately.

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

#1


8  

This code:

这段代码:

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

is returning the address of a thread-local variable. %fs:0x0 is the address of the TCB (Thread Control Block), and 1069833(%rip) is the offset from there to the variable, which is known since the variable resides either in the program or on some dynamic library loaded at program's load time (libraries loaded at runtime via dlopen() need some different code).

返回一个线程局部变量的地址。 %fs:0x0是TCB(线程控制块)的地址,1069833(%rip)是从那里到变量的偏移量,这是已知的,因为变量驻留在程序中或程序中加载的某个动态库上加载时间(通过dlopen()在运行时加载的库需要一些不同的代码)。

This is explained in great detail in Ulrich Drepper's TLS document, specially §4.3 and §4.3.6.

这在Ulrich Drepper的TLS文档中有详细解释,特别是§4.3和§4.3.6。

#2


3  

I'm not sure they've been called segment register since the bad old days of segmented architecture. I believe the proper term is a selector (but I could be wrong).

我不确定他们自从分段架构的旧时代以来就被称为段寄存器。我相信正确的术语是选择器(但我可能是错的)。

However, I think you just need at the first quadword (64 bits) in the fs area.

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

The %fs:0x0 bit means the contents of the memory at fs:0. Since you've used the generic add (rather than addl for example), I think it will take the data width from the target %rax.

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

In terms of getting the actual value, it depends on whether you're in legacy or long mode.

在获取实际值方面,这取决于您是处于遗留模式还是长模式。

In legacy mode, you'll have to get the fs value and look it up in the GDT (or possibly LDT) in order to get the base address.

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

In long mode, you'll need to look at the relevant model specific registers. If you're at this point, you've moved beyond my level of expertise unfortunately.

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