以x86为基准
最早的分段出现在8086,8088,不过还是实模式,这时也可以称为动态重定位,寻址方式为cs*16 + 偏移地址,偏移地址为代码要访问的地址
例如jmp 128,则128就是偏移地址,这时的每个进程运行在自己的地址空间,使用的也是逻辑地址,经过地址变换以后生成线性地址,若没有分页机制,则线性地址就是物理地址了
不过早期的段机制没有保护,可以修改cs寄存器访问其他进程的代码段
后来的286,386形成了保护模式下的段机制,这时开始使用段表(GDT)来记录特权级别,cs寄存器中的值也不是地址了,而是段表项在段表中的索引号
这是段寄存器的结构,index即为索引号
这是段表项的结构
一个GDT的表项占8字节
G表示limit的单位,0为1byte,1为4kb(Intel的固定页面大小),所以一个段的最大值为1MB或4GB
base address即为程序段的基地址,32bit
GDTR的结构
其中的base address为段表的基地址
limit为段表的长度,2^16=64kb,64kb/8byte=8192,也由此可知一个段表最多有8192项
cs代码段寄存器,16位,其中13位为段选择子, 2^13也等于8192。。。。
寻址的基本路线:例如执行jmp 28,先从GDTR中找到段表的地址(32bit),再用cs中的索引号查段表项的位置,再从段表项中找到程序段的地址,这时程序段的地址+28生成线性地址,若无分页机制,线性地址就是物理地址
其实还有LDT和LDTR,原理同GDT一样