段描述表Descriptor Table

介绍了80386处理器在保护模式下如何通过段描述符和段选择器实现内存访问控制。包括段描述符表、全局描述符表寄存器GDTR及局部描述符表寄存器LDTR的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

80386在保护模式下,一个地址空间是否可以被写入,可以被多少优先级的代码写入,是不是允许执行等涉及到保护的问题需要解决.要解决这些问题,必须对一个地址空间定义一些安全属性.段寄存器这时就派上用场.但是涉及的信息量太大,段寄存器无法存储,要用64位长的数据才能表示,我们把这64位的属性数据叫做段描述符Segment Descriptor.

 

由于段寄存器无法放下这64位的为数据,所以以如下方法解决.

将所有段的段描述符顺序放在内存中的指定位置,组成一个段描述符表Descriptor Table.用16位的段寄存器来做索引,指定这个段的属性是由段描述表中的哪个描述符指定的.此时称16位段寄存器为段选择器Segment Selector.

 

而段描述符表是由一个48位的全局描述符表寄存器GDTR和一个16位的局部描述符表寄存器LDTR来指定的.

 

GDTR指向GDT,GDT只有一个.

LDTR指向LDT.每个任务都有一个独立的LDT.LDTR存放指向LDT内存段对应描述符在GDT中的位置.

 

所以,GDTR是直接指向内存中GDT的地址的,而LDTR是索引.

 

选择器高13位表示索引值,第0,1位表示程序当前优选级RPL.第2位TI用来表示段描述符的位置.TI = 0 表示在GDT中,TI =1表示在LDT中.

 

索引过程:

 

TI = 0;

 

GDTR -> GDT -> 在GDT中,用段选择器高13位索引,得到段描述符,描述符中包含了基址,限长,优先级等属性,于是得到了段的基址.

 

TI = 1;

 

GDTR -> GDT -> 在GDT中,用LDTR作为索引,得到LDT的描述符a,描述符a中有LDT的信息,所以找到LDT -> 在LDT中,用选择器的高13位索引,得到段描述符b.

描述符b中有基址,限长,优先级等属性,于是得到了段的基址.

 

以上两种方法得到的基址后,再加上偏移地址,得到线性地址.

 

 

### 文件描述分配失败导致内存不足的问题 当操作系统尝试为新打开的文件创建新的文件描述符时,如果内核无法找到足够的连续空间来扩展进程的文件描述,则会发生 `unable to allocate file descriptor table out of memory` 错误。这通常意味着系统资源已经耗尽。 #### 解决方案概述 为了处理这种情况,可以采取多种措施: 1. **增加文件描述符限制** 可以通过调整操作系统的配置参数来增大单个进程中允许的最大文件描述符数量。对于Linux系统而言,可以通过修改 `/etc/security/limits.conf` 来设置软硬限制[^1]。 2. **优化程序设计减少不必要的文件句柄占用** 定期关闭不再使用的文件句柄可以帮助释放宝贵的资源。确保所有的输入输出流在完成读写之后都被正确关闭是非常重要的。 3. **检查并清理僵尸进程** 僵尸进程可能会持有大量未释放的文件描述符,因此定期监控和清除这些无响应的任务有助于缓解此问题。 4. **使用更高效的API管理大容量数据传输** 对于频繁涉及大数据量的操作场景下,考虑采用如 `mmap()` 这样的高级接口替代传统的 I/O 函数可能更加合适,因为前者可以直接映射文件到虚拟地址空间从而减轻了对文件描述符的需求压力。 5. **重启服务或机器作为临时解决方案** 如果上述方法都不能立即解决问题,在不影响业务的前提下可以选择重启相关服务甚至整个服务器实例来进行快速恢复。 ```bash ulimit -n 65535 # 设置当前shell会话中的最大文件数限制 ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值