Poo*_*998 3 assembly x86-64 cpu-registers memory-segmentation addressing-mode
在 x86_64 中,fs 和 gs 寄存器涉及有限形式的分段。就以fs为例,fs寄存器、FSBase MSR是如何协同工作生成有效地址的呢?
如果我更改 fs 基数而不更改 fs,会发生什么情况?还是更改 fs 基础会自动更改 fs?
如果我更改 fs 寄存器而不更改 fs 基数会怎样?如何影响有效地址计算?
我们可以举一个简单的例子
mov %fs:(%eax), %ebx
Run Code Online (Sandbox Code Playgroud)
FS 架构寄存器与基于 FS 的内部寄存器是分开的。
与往常一样,使用段覆盖仅选择与该段关联的段基,而不是默认的 DS 基或 SS 基(0在 64 位模式下固定)。
fs架构寄存器中的实际值本身与它无关。只有当您mov %fs, %eax要实际读取 FS 寄存器本身而不是使用与其关联的内部基数/限制“寄存器”时,它才会起作用。
由于有一些方法可以设置内部 FS 基础(例如,使用wrmsr或在更新的 CPU 上使用wrfsbase指令)比mov设置更有效%fs(使其从 GDT 或 LDT 加载基础和限制),操作系统通常离开 FS 和 GS 架构registers = 0,空选择器。
在裸机上,您也可以这样做。不要费心创建带有您想要的基数的 GDT 条目并将mov选择器放入%fsor 中%gs;只需直接使用wrmsr或设置基数即可wrfsbase。
如果我更改 fs 寄存器而不更改 fs 基数会怎样?
你不能,AFAIK。 mov %reg/mem, %fs将触发从 GDT 或 LDT 加载内部段基址/限制寄存器(取决于您 mov 的值)。
请注意,有些人将这些内部事物称为“缓存”,但它们不是缓存。它们保证在您加载它们时保留这些值,因此如果您更改 GDT 条目而不用该选择器重新加载段寄存器,它们将永远不会发生更改。
如何影响有效地址计算?
和往常一样。基础 + 指数 * 比例 + 位移。请注意,“有效地址”只是完整地址的偏移部分,不包括段选择器或基址。 什么是有效地址?
的线性地址也被计算与往常一样:segment_base + offset,其中偏移部分是由寻址模式所指定的有效地址。
寻址模式默认使用 DS 段基址,除非寻址模式中的“基址寄存器”是 E/RBP 或 E/RSP,在这种情况下它是 SS 基址。但是前缀字节可以覆盖默认值;这就是%fs:告诉汇编程序发出的内容。