数据结构指针

在论坛常看到有人问关于指针的问题,已经运行时候出错,或者程序崩溃,或者打印数据不对;或者段错误;
所以写篇文章希望对大家有用;
1;首先谈谈段;在intel处理器中逻辑地址;线性地址;物理地址;逻辑地址就是段地址+段内偏移量;在早期的8086中;逻辑地址是16位段地址×16+段内偏移量;到了后来;intel引入了所谓的实模式和保护模式;所谓实模式也是就兼容早期的8086;段地址依然是段寄存器内容;逻辑地址依然是段地址×16+段内偏移量;所谓保护模式是对于逻辑地址另外一种算法;
线性地址就是我们用段寄存器内容×16+段内偏移量算出的地址;很显然早期的地址只有20位;一种到引入MMU;就有了物理地址的和线性地址的区别;如果没有硬件MMU;那么线性地址就是时间的物理内存的地址;但是引入了MMU;这个线性地址将被MMU控制器重新解析;然后解析到不同的物理地址;这个就是所谓的分页技术;
2;谈到寄存器,我们不妨列出所有的寄存器EAX;EBX;ECX;EDX;ESP;EBP;EDI;ESI;这个8个叫通用寄存器;EIP;EFLAGS;是特殊寄存器;还有CS;DS;ES;SS;FS;GS这些段寄存器;这个里面的内容将作为段的首地址;8086的寄存器没有E;也就是说是AX;BX等;
3;指针;我们知道指针表示地址;我们也常说32bit的系统;指针长度是4字节的;那么这个4字节的内容最后到达写到哪里去呢?毫无疑问;这个指针的内容会被分为段地址和段内偏移量2个部分;段地址部分被存放到段寄存器中;(当然了保护模式下,寄存器的解析是不同于是模式的)在进一步解释指针之前;以及野指针问题;我们来看看保护模式;
4;保护模式;在现在的操作系统中都是开始用实模式;后来用保护模式;正是由于保护模式的存在;才让编程变得容易;
实模式有个缺点就是只能寻1M空间;也就是20位;对于保护模式;有一个8字节的段描述符;这个描述符描述你一个段的基本信息;包括段的起始地址;段的大小;段的颗粒大小;这里有必要说说段的大小和颗粒大小的问题;其实段的大小只是说段从起始地址开始;有多少个颗粒大小;颗粒可以是1byte;也可以是4kbyte;段就是只得颗粒的数量;段大小是20位的;如果颗粒是1byte那么段的最大就是1M;如果颗粒是4k;那么最大就是4G;
好了;那么我们一共有多少个这样的段描述符呢;换句话说我们有多少个段可以使用呢?这个时候16bit的段寄存器不再像实模式那样解释了;16bit的前13bit作为段选择符;后面3bit作为这个段的描述;这里我们不得不说GDT;LDT;GDT;和LDT;是2张表;这个2张表放着段描述符的地址;这个表有13^2个表项;好了现在我们知道所有的寄存器都有13bit的选择子;指示了选择GDT或者LDT表中段描述符的序号;比如说CS=0008H;那么我们知道;前13bit值是1;后面3bit是000;那么他将选择第2个标识符;那么GDT;LDT是什么呢?他们叫全局描述符和局部描述符;一个CPU只有1个GDT;而每个应用程序都可以有一个LDT;GDT;LTD的起始地址存放在寄存器GDTR;LDTD中;
5;说完了intel的段;我们再来看看分页机制;在linux中;并没有用到13^2个段;4个主要的段是内核的代码段;内核的数据段;应用程序代码段;应用程序数据段;他们都设置了段描述符使得其实地址是00000000H;结束地址是FFFFFFFFH;开始我们说段寄存器最后3位用作其他作用;其中一个就是设置CPU访问权限;2bit一个用4中权限;linux只用了0和3;也就是我们平时说的内核态和用户态;对于intel处理器来说如果CPU的寄存器cr0到cr4;里面有说明CPU访问权限;(我没有具体研究过)当CPU访问权限小于段的访问权限那么段是无法被访问的;也就是说CRX中如果说明CPU权限是3;而段权限是0;那么CPU是无法访问这个段的;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值