嵌入式指针及相关概念

  • 尾端 (Endianness)

尾端由Danny Cohen(Cohen 1980)由一篇论文引入计算机界,作者注意到计算机体系结构基于字节寻址和整数定义在通信系统中的不同定义分为“大尾端”(Big-endian)和“小尾端”(Little-endian)两个阵营。一个十六进制整形数据0x12345678传递给另外一个采用不同尾端的计算机系统时可能会被理解为0x78563412甚至0x1E6A2C48。这就是尾端命题。尾端直接决定着数据在存储器内的组织形式。

  • 地址空间 (Address Space)

存储器中,由存储单元地址或集合所构成的集合称为地址空间。

  • 线性地址空间 (Linear Address Space)

如果一个地址空间中所有的元素可以组成一个由整数构成的唯一闭区间,则称该地址空间为线性地址空间。

  • 扁平地址空间 (Flat Address Space)

一个地址空间可以由多个不同纬度的线性地址空间构成,当地址空间中只有唯一的一个线性地址空间时,或者地址空间中不同的线性地址空间可以被影射到同一个彼此不相交的纬度时,则称该地址空间为扁平地址空间。

  • 内存组织方式

除去字节、字符、字符串和字节流,C语言中几乎所有的数据类型,准确说是这些数据类型在存储器内部的组织方式都要受到尾端的影响。出于历史的原因,IBM及其兼容的计算机系统采用大尾端系统,习惯上又被称为大端对齐系统;DEC和Intel及其兼容的计算机系统采用小尾端系统,习惯上又称为小端对齐系统。
只有在进行字节寻址时才会有尾端的问题。早期计算机工程师在20世纪60年代晚期都是对单字节进行操作:指令、整型和内存宽度都是相同的字宽度。这样的计算机系统不存在尾端的概念,只有字在内存中的顺序、以及字内部二进制位序的问题。
我们在书写十进制数字式,都是先写高位再写低位;对数据的读取也采用同样的方式。为了符合这一习惯,IBM的工程师们尝试寻找一种以字为单位的数值表示方法。当我们按照习惯将内存单元按照从左到右地址增加的顺序依次排列开来,可以发现字的数值是直接可读的,或者说字的表示形式符合人们从左至右、从高位开始读取数字的习惯。(如图12.1所示)此时,由于存储器从左到右地址是依次递增的,字节内二进制位序从左到右也是依次递增的关系,因而在一个字内,二进制位序实际上与数值的位序正好相反。这就是大尾端的形成原因。
另一方面,我们也习惯于很自然的给每一个字节的二进制位赋予一个权值,比如BIT0的权值为1、BIT1的权值为2、BIT2为4……BIT7为128,这实际上就是将字节的二进制位序作为该位权值以2位底的幂指数,简单的说,BITn的权值就等于2n。用这种顺序可以非常自然的由多个字节组成较大的数据类型,这就是小尾端形成的原因。

  • 硬件与尾端

在物理上,大尾端以字为单位组织数据(如图12.1大尾端图示的粗横线所示),字内的位序与实际的物理位序完全相反。大尾端认为,在字内第一字节物理位0为最高位(MSB,Most Significant Bit);第四字节物理位7为最低位(LSB,Least Significant Bit)。小尾端以字节为单位组织数据,数据元素的字节序与存储器的字节序相同,字节内部的位序也与物理位序相同:物理位0为最低位LSB、物理位7位最高位MSB。
对比图12.1中两种尾端对十六进制数字0x12345678的组织形式很容易发现:当我们把存储器按照从左到右地址依次增加的顺序排列开来的时候,小尾端系统读取到的数据依次为0x78、0x56、0x34和0x12;大尾端读取到的数据依次为0x12、0x34、0x56和0x78,符合人们的阅读习惯。在大尾端系统中,数据的组织必须以字为单位,否则因为逻辑位序与物理位序的冲突而导致数据的混乱。在大尾端系统中,CPU内核与存储器往往都是按照大尾端形式组织数据的;在小尾端系统中,CPU与存储器往往都是按照小尾端形式组织数据的;外设与总线的尾端往往可以根据不同的设计需求而有所不同。

存储器大尾端和小尾端结构示意图(表示十六进制数字0x12345678)

  • 存储器对齐方式

很多计算机系统为了寻址的便利,或者由于数据操作类型的限制(例如,AVR32每次只能以32位数据为单位进行读写操作)要求用户将数据或变量尽可能的对齐到指定的地址上。32位计算机往往要求用户将数据对齐到字(WORD,4Byte)或者半字(Half WORD,2Byte),AVR作为8位微处理器,以字节为单位进行寻址,因而对用户没有数据对齐的要求。使用C语言进行软件开发时,编译器会自动对用户声明的变量按照处理器的要求进行对齐,例如,针对下面的全局变量声明,字对齐模式下的内存示意如图所示;半字对齐模式下的内存示意如图所示;字节对齐模式下的内存示意如图所示:

1 /* 使用C99标准数据类型 */
2 #include <stdint.h>
3 /* 全局变量声明 */
4 uint8_t a;
5 uint16_t b;
6 uint32_t c;

posted on 2012-09-18 14:24  竞击  阅读(739)  评论(0编辑  收藏  举报