Precondition: 80X86体系架构
操作系统的逻辑地址,指的是机器语言中用来指定一个操作数或者一条指令的地址。
很多人把这个地址说的非常悬乎,二维啊什么的,简单的一句话就是每个地址都是段(segment)和偏移量(offset)组成。
很多时候我们遇到segment failure,指的就是段。
1. 段的种类
代码段, 栈段,数据段等
2. 段寄存器
CS: 代码段寄存器
SS: 栈段寄存器
DS: 数据段寄存器
ES:
FS:
GS:
3. 段选择符(segment selector)
段选择符就是一个16位长的字段,都是放在段寄存器中。
4. 段描述符(segment descriptor)
段的内容,一般由段描述符来描述。段描述符一般有8个字节长,描述的内容有段首字节的线性地址(用于地址转换), 段的类型, 段的类型, 段的权限等等。
段描述符一般放在两个表中,一个是全局描述符表,一个是局部描述符表。
5. 全局描述符表(global descriptor table)和局部描述符表(local descriptor table)
GDT的地址和大小在gdtr控制寄存器中,LDT的地址和大小在ldtr控制寄存器中。
<=================================================>
在Linux系统中,有四个最主要的段描述符,分别是用户代码段、用户数据段、内核代码段和内核数据段,他们的地址都是从0x00000000开始的,而段的偏移量可以是32位的,因此,在用户态和内核态下所有的进程可以使用相同的逻辑地址。
所以,在Linux下逻辑地址和线性地址是一致的, 逻辑地址的偏移量字段的值和相应的线性地址的值总是一致的。
在单处理器系统中,只有一个GDT,在多处理器系统中每个CPU对应一个GDT。每个GDT包含18个段描述符和14个空的,主要包括内核态的代码段、内核态的数据段、用户态的内核段、用户态的数据段、任务状态段(TSS)。。。。
大多数用户态下的Linux程序不使用LDT。
More:
http://www.cublog.cn/u3/90876/showart_2033844.html
http://www.cublog.cn/u1/35334/showart_278335.html