LDT是局部描述符表,主要存放各个任务的私有描述符,如本任务的代码段描述符和数据段描述符等。
GDTR是一个长度为48bit的寄存器,内容为一个32位的基地址和一个16位的段限。其中32位的基址是指GDT在内存中的地址。
LDTR是局部描述符寄存器,由一个可见的16位寄存器(段选择子)和一个不可见的描述符寄存器组成(描述符寄存器实际上是一个不可见的高速缓冲区)。
这里加入我的理解:应为GDT中除了有段描述符之外还有LDT描述符,所以微处理器在GDT中寻址LDT时,也需要使用选择子,以保持与段描述符寻址的统一。
在这里还要引入一个段选择子的概念。段选择子是一个寄存器,高13位用来指示描述符在描述符表中的索引号,低两位是表示使用描述符的特权级别;另外一位(T1)是GDT和LDT的信号量,如果T1=0,则使用GDTR,如果T1=1,则使用LDTR。选择子将被装入段寄存器中。系统中的段寄存器共有六个:CS、SS、DS、ES、FS和GS。当选择子被装入段寄存器时,微处理器会自动将其对应的描述符装入描述符寄存器。
系统任务切换时,LDT切换,而GDT不切换(因为真个系统只有一个GDT),这时新任务的LDT描述符的选择子就被装入到LDTR中。
任务切换过程中,各个相关寄存器的变化?
当 任务切换时,如果使用的是LDT,首先变化的是LDTR。段选择子被装入LDTR,同时LDT描述符自动被装入描述符寄存器。系统利用LDTR中的段选择 子来定位LDT描述符在GDT中的位置。这里我不明白的是LDTR中的LDT描述符和GDT中的描述符是什么关系?为什么要这样做呢?自动装入到LDTR 中的描述符到底是什么?从哪来?请高手指点!
为什么要有一个GDTR,并且GDTR的结构和LDTR不一样呢?
这主要是因为系统只有一个GDT,而GDT的描述符有不能存放在GDT中(LDT的描述符都存放在GDT中),所以就需要一个GDTR来指示GDT在内存中的位置。因为GDTR是直接指示内存地址,而LDTR主要指示LDT描述符在GDT中的位置和属性,所以GDTR和LDTR的结构也不同。
主要有以下几个方面的原因:
一、内存访问出错
这类问题的典型代表就是数组越界。
二、非法内存访问
出现这类问题主要是程序试图访问内核段内存而产生的错误。
三、栈溢出
Linux默认给一个进程分配的栈空间大小为8M。c++申请变量时,new *** 作申请的变量在堆中,其他变量一般在存储在栈中。
因此如果数组开的过大变会出现这种问题。
扩展资料:注意事项
段错误一般就是指访问的内存超出了系统所给这个程序的内存空间,通常这个值是由gdtr来保存的,他是一个48位的寄存器,其中的32位是保存由它指向的gdt表,后13位保存相应于gdt的下标,最后3位包括了程序是否在内存中以及程序的在cpu中的运行级别,指向的gdt是由以64位为一个单位的表,在这张表中就保存着程序运行的代码段以及数据段的起始地址以及与此相应的段限和页面交换还有程序运行级别还有内存粒度等等的信息。
一旦一个程序发生了越界访问,cpu就会产生相应的异常保护,于是segmentation fault就出现了。在编程中基本是是错误地使用指针引起的。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)