我已经使用这些数据设置了gdt表。
uint16_t gdt_table[][4] = {
{ 0, 0, 0, 0 },
{ 0xFFFF, 0x0000, 0x9a00, 0x00cf },
{ 0xFFFF, 0x0000, 0x9200, 0x00cf },
};
我做mov $16, %eax
; mov %eax, %ds
以使用GDT条目加载DS。
现在我改变了gdt_table,或者只是将其设置为零(以干扰它),但不再重新加载%ds
。
这些是我的问题
- 我想知道是否仍然可以通过
%ds
访问数据(在我扰乱gdt表后) - 每次我通过
%ds
访问数据时,cpu会检查gdt表吗?(那么什么时候cpu会检查gdt表,只有在mov时?还是每次我通过数据段寄存器访问数据时?)
我认为cpu应该只在mov
发生的时候检查gdt表,然后在某个地方加载一些信息,这样可以更有效(通过减少检查频率),对吗?
1条答案
按热度按时间8ftvxx2r1#
我想知道是否仍然可以通过%ds访问数据(在我扰乱gdt表之后)
这是安全的;除非稍后有东西从GDT重新加载%ds。对于中断处理程序来说,保存“被中断代码的DS”,然后在返回被中断代码之前再次加载它,这并不罕见。
每次我通过%ds访问数据时,cpu会检查gdt表吗?
为了提高性能(避免重复访问GDT和进行保护检查),CPU将(段基址、限制、属性)信息缓存在段寄存器的“隐藏”部分。在向/从SMM转换以及在客户机和管理程序之间转换期间,也会保存和重新加载此信息;因此GDT也不用于这些情况。
CPU将访问DS的GDT的唯一情况是存在DS的显式加载(一个
mov
、lds
或pop ds
),或硬件任务开关(例如,使用任务门)。对于“中断处理程序返回到虚拟8086模式”(CPU从DS恢复值)不使用GDT,因为CPU正在加载真实的模式兼容值。对于CS和SS(但不是DS)CPU在使用中断/陷阱门或调用门并返回(通过.iret
或retf
)时也将使用GDT。