记一个被自己忽略的知识点(指针本身的长度到底由什么决定)

     通常我们计算指针的长度会用到sizeof(void*),我一直片面的任务指针的大小和int类型的大小是一样的,但是在一次core dump崩溃调试的过程中看到一个指针的长度竟然是64位的就以为指针是个野指针,但是最后发现问题不在那里,指针是正确的,这我才进一步的了解了指针大小到底是由系统什么因素决定的。
    首先我们说下数据总线和地址总线
    1)地址总线
      地址总线决定了cpu的寻址能力,要存取数据或指令就要知道数据或指令存放的位置,地址寄存器存储的就是CPU当前要存取的数据或指令的地址,该地址是由地址总线传输到地址寄存器上的。假设地址总线有n位,即共有n位二进制位来表示地址,那么最多可以表示2^n个地址,另外,由于计算机以一个字节为寻址单位,所以CPU的寻址能力或者说最大寻址范围为2^n个字节。
      综上,地址总线的位数决定了CPU的寻址能力。例如32位的地址总线,每根地址线传输一位,可表示的范围为0~2^32-1,所以也就对应0~2^32-1 byte,也就是0~4GB,也就是说如果你的电脑的地址总线是32位的,那么你的电脑支持最大的内存只有4个G。
    2)数据总线
     通常,我们所说的一个芯片是多少位的,到底是看它的数据总线宽度还是地址总线宽度呢?
     答案是:决定一个芯片多少位,是由这个芯片一次能处理多少位数据决定的,等于片内寄存器的宽度,同时可以看成是数据总线的宽度。为什么这里说的是芯片位数可以看成是数据总线的宽度而不是等于数据总线的宽度呢?按照目前的情况而言,几乎所有的芯片位数都等于数据总线宽度。为什么呢?
     在地址寄存器指出要存取数据或指令的位置后,接下来就是到该地址把数据或指令找到,并用数据总线传输给CPU。假设数据总线有m位,则传输的数据或指令也有m位。而字长指CPU同一时间内可以处理的二进制数的位数,所以数据总线传输的数据或指令的位数要与字长一致。否则,如果数据总线宽度大于字长则一条数据或指令要分多次传输,则分开传输的几组数据也就没有意义了,如果数据总线宽度小于字长,则CPU的利用率要降低,对资源是种浪费。另外,如果字长为n位,一般称CPU是n位的。所以数据总线的宽度与字长及CPU的位数是一致的。
     一个常见的误区是:地址总线和数据总线的宽度总是保持一致的。举一个数据总线和地址总线宽度不同的例子:在经典的8086计算机中,数据总线为16位,地址总线则是20位。
不过,芯片设计者为了平衡时间效率和空间效率,同时考虑到硬件上的影响,通常使用同样的地址总线宽度和数据总线宽度。
    3)最后说到指针的长度指针的长度到底是由数据总线还是地址总线又或者是编译器决定的呢?
    首先指针本身存储了一个值,这个值保存了一个地址,该地址指向了一块内存区域,如果我们想要访问所有的可用内存,由于内存的大小由地址总线的宽度决定的,所以从理论上来说,这个指针类型的宽度至少要大于等于地址总线的宽度,所以指针的大小实际上是由寻址宽度决定的,最后指针的长度是不是一定和寻址宽度一样呢?
看下面实际的情况:
  32位处理器上32位操作系统的32位编译器,指针大小4字节。
  32位处理器上32位操作系统的16位编译器,指针大小2字节。  
  32位处理器上16位操作系统的16位编译器,指针大小2字节。
  16位处理器上16位操作系统的16位编译器,指针大小2字节。
        Intel 32位处理器32位运行模式,逻辑寻址位数32,指针也就是32位,即4个字节
     Intel 32位处理器16位虚拟机运行模式,逻辑寻址位数16,指针也就是16位,即2个字节
  编译器的作用是根据目标硬件(即CPU)的特性将源程序编译为可在该硬件上运行的目标文件。如果一个编译器支持某32位的CPU,那么它就可以将源程序编译为可以在该CPU上运行的目标文件。该源程序中指针大小也会被编译器根据该CPU的寻址位数(如32位)编译选择为4字节。
      芯片的位数由芯片一次能处理的数据宽度决定,可看成是数据总线的宽度,但是地址总线和数据总线的宽度有时候并不一致。所以在经典的32位系统中,同时也是32位地址总线,自然而然的,指针的长度为32位。但是对早期的8086而言,这是16位芯片,但是它的地址总线却扩展到了20位,同时因为数据对齐的原因,它的指针大小应该是16+16位=32位,但是出于效率上的优化,8086提供了远指针、近指针,在访问本段内的地址时,采用16位指针,如果有段地址跳转,就使用32位的指针。至少从这个示例可以知道,指针的大小完全由实际使用的地址总线的宽度(+数据对齐)来决定,而并非由芯片位数来决定。
所以,有时候,我们可能会在64位系统中碰到指针大小为4字节的情况,也可能在16位系统中碰到指针大小为4字节的情况。当然,需要特别注意的是,在64位系统中地址大小为4字节的情况下,并非一定是芯片的地址总线是32位,很可能是CPU运行在只使用部分地址总线的模式下,又或者是使用32位兼容的编译器所致。
      因此在通常情况下指针的长度是和寻址宽度一样的,如果不一样很有可能是由于操作系统的位数和编译器的位数的异常导致运行模式不同造成的。
   

    

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值