fs和gs寄存器如何计算有效地址

How is effective address calculated with fs and gs registers

在x86_64中,fs和gs寄存器涉及有限形式的分段。仅以fs为例,fs寄存器,FSBase MSR是如何协同生成有效地址的?

如果我在不更改 fs 的情况下更改 fs base 会怎样?还是改变fs base会自动改变fs?

如果我在不更改 fs 基址的情况下更改 fs 寄存器会怎样?有效地址计算如何受到影响?

我们可以举一个简单的例子

mov %fs:(%eax), %ebx

FS 体系结构寄存器与 FS-base 内部寄存器是分开的。

与往常一样,使用段覆盖只会选择与该段关联的段基数,而不是默认的 DS 基数或 SS 基数(在 64 位模式下固定为 0)。

fs架构寄存器本身的实际值与它无关。只有当你要 mov %fs, %eax 实际读取 FS 寄存器本身,而不是使用与其关联的内部基数/限制 "registers" 时,它才会发挥作用。

因为有一些方法可以设置内部 FS 基础(例如使用 wrmsr 或在更新的 CPU the wrfsbase instruction 上)比 mov%fs 更有效(使其从 GDT 或 LDT 加载基数和限制),操作系统通常保留 FS 和 GS 体系结构寄存器 = 0,空选择器。

在裸机上,您也可以这样做。不要费心用你想要的基础创建一个 GDT 条目,然后 mov 将选择器插入 %fs%gs;只需直接使用 wrmsrwrfsbase.

设置基数

What happens if I change fs register without changing fs base?

你不能,据我所知。 mov %reg/mem, %fs 将触发从 GDT 或 LDT 加载内部段基址/限制寄存器(取决于您移动的值)。

请注意,有些人将这些内部事物称为 "cache",但它们不是缓存。它们保证保留您加载它们时的值,因此如果您更改 GDT 条目而没有使用该选择器重新加载段寄存器,它们永远不会发生变化。

How are the effective address calculations affected?

一如既往。基础 + 索引 * 比例尺 + 位移。请注意,"effective address" 只是完整地址的偏移部分,不包括段选择器或基址。

线性地址也照常计算:segment_base + offset,其中偏移部分为寻址方式指定的有效地址。

寻址模式默认使用 DS 段基址,除非寻址模式中的 "base register" 是 E/RBP 或 E/RSP,在这种情况下它是 SS 基址。但是前缀字节可以覆盖默认值;这就是 %fs: 告诉汇编程序发出的内容。