当激活时(即TR寄存器指向的那个)TSH的字段发生变化会发生什么?特别是,对ESP0 / RSP0字段的更改是否立即生效?或者处理器是否与段选择器一样保留TSS的高速缓存,因此需要LTR指令来强制处理器重新加载TSS字段?
答案 0 :(得分:6)
处理器使用TSS存储当前上下文并在任务切换期间加载下一个要调度的上下文。
在CPU切换到此类TSS之前,更改TSS结构不会影响任何上下文。
当
时,CPU执行任务切换软件或处理器可以通过以下方式之一派遣任务执行:
•使用CALL指令显式调用任务 •使用JMP指令显式跳转到任务 •(通过处理器)对中断处理程序任务的隐式调用 •对异常处理程序任务的隐式调用 •当EFLAGS寄存器中的NT标志置位时,返回(使用IRET指令启动)。
您可以阅读英特尔手册3第7章中的TSS。
<div class="grid-box">
<div class="first-row">
<div class="grid one">
<img src="http://placehold.it/100x100" alt="" />
</div>
<div class="grid two">
<img src="http://placehold.it/100x100" alt="" />
</div>
</div>
<div class="grid three">
<img src="http://placehold.it/202x100" alt="" />
</div>
</div>
没有执行交换机,请参阅英特尔手册2:
在任务寄存器中加载段选择器后,处理器使用段选择器来定位 全局描述符表(GDT)中TSS的段描述符 然后加载段限制和基数 TSS从段描述符到任务寄存器的地址 任务寄存器指向的任务是 标记为忙,但没有发生任务切换。
编辑:我实际测试了CPU是否缓存了来自TSS的静态值。
测试包括一个启动程序(附件)
X509Store store = new X509Store();
store.Open(OpenFlags.ReadOnly);
if (args.Parameters["CertificateName"].ToString() != "")
{
foreach (X509Certificate2 mCert in store.Certificates)
{
if (mCert.Subject.Contains("OU=" + args.Parameters["CertificateName"].ToString()))
{
SerialNum = mCert.SerialNumber;
break;
}
}
if (SerialNum == String.Empty)
{
throw new Exception("Certificate not found with name: " + args.Parameters["CertificateName"].ToString() + " ;" + " OU=" + args.Parameters["CertificateName"]);
}
}
else
{
foreach (X509Certificate2 mCert in store.Certificates)
{
if (mCert.Subject.Contains("OU=Eua"))
{
SerialNum = mCert.SerialNumber;
break;
}
}
if (SerialNum == String.Empty)
{
throw new Exception("Haven't found default certificate ;");
}
}
store=null;
。 在我的Haswell和Bochs上,结果是2,这意味着CPU在需要时从内存(层次结构)读取TSS。
虽然对模型的测试不能推广到ISA,但事实并非如此。
ltr
答案 1 :(得分:4)
只在必要时才读取TSS,并且没有特殊的TSS缓存。 (GDT中的TSS描述符与段描述符一样缓存,但不是TSS本身的内容.TSS可以像任何其他内存区域一样缓存在普通的L1 / L2 / L3内存缓存中。)
在不同情况下可以读取TSS的三个不同区域。在适当的情况发生之前,更改TSS中的任何值都无效。他们是:
请注意,在64位模式下,只有情况1,3和5可能发生,因为64位模式不支持Virtual 8086模式,也不支持任务切换。
LTR指令不会导致读取任何内存区域,除了GDT中与给定选择器对应的条目,也没有任何内部TSS缓存供它冲洗。