`
soboer
  • 浏览: 1321188 次
文章分类
社区版块
存档分类
最新评论

不同体系结构的处理器的大小端模式 .

 
阅读更多
所谓的大端模式,是指数据的低位(就是权值较小的后面那几位)保存在内存的高地址中,而数据的高位,保存在内存的低地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;

  所谓的小端模式,是指数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低,和我们的逻辑方法一致。

为什么会有大小端模式之分呢?这是因为在计算机系统中,我们是以字节为单位的也是以字节为单位来寻址的,每个地址单元都对应着一个字节,一个字节为 8bit。但是在C语言中除了8bit的char之外,还有16bit的short型,32bit的long型(要看具体的编译器),另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如果将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。例如一个16bit的short型x,在内存中的地址为0x0010,x的值为0x1122,那么0x11为高字节,0x22为低字节。对于大端模式,就将0x11放在低地址中,即0x0010中,0x22放在高地址中,即0x0011中。小端模式,刚好相反。我们常用的X86结构是小端模式,而KEIL C51则为大端模式。很多的ARM,DSP都为小端模式。有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。

大小端的问题,主要是由于字长大于8bit的处理器,在处理一个字的时候,将其拆分成多个字节的表示方法。对于大端处理器,高位在低地址,低位在高地址。如0x12345678,在内存中这样表示:
地址78797a 7b
数据 12 34 56 78
对于这个32位的整数在内存中的存放位置,在X86中由于是32位的处理器所以在内存中寻址的地址也为32位,每个32位的地址寻址一个字节,假设存放这32位整数的起始地址为0x0012ff78,则在x86这样的小端模式中存放顺序依次为78,56,34,12,为什么不是直接反序(87,65,43,21),我们知道在内存中都是以字节为单位来寻址的,所以存放数据的最小单位也就是字节。一般,ARM/MIPS/PPC都是大端处理器。

而对于小端处理器,低位在低地址,高位在高地址。0x12345678这样排列:
地址 00 01 02 03
数据 78 56 34 12
x86属于小端。

这两种排列方法没有好坏之分,但是,对于不同体系结构的处理器之间通讯的时候,有可能产生问题。如MIPS机器发送0x12345678,到了x86接收的时候,就成了0x78563412。
试想,如果通讯中发生这种错误,多可怕啊——

“呼叫021,呼叫021”

那边,120收到了:“收到呼叫,收到呼叫”

“炮轰3309地区!”

“明白,炮火覆盖9033地区”~

于是,无数我方战士被自己人的炮火……


因此,人们制定了网络字节序——和大端字节序一致,高字节先发,低字节后发。这样,对于x86和MIPS/ARM/PPC处理器,对数据的处理流程就不一样了。x86需要将收到的数据按字节序颠倒以后处理,而MIPS/ARM/PPC可以直接处理。编写程序的工程师们为了让代码可移植,定义了以下的宏:
htonl /× 主机序转网络序,long int类型 ×/
ntohl /× 网络序转主机序,long int类型 ×/
htons /× 主机序转网络序,short int类型 ×/
ntohs /× 网络序转主机序,short int类型 ×/
对于小端处理器,这个宏返回颠倒字节序后的值,而对于大端处理器什么都不做。

通过一个联合体的例子来在各个不同平台下来做做实验:

有这样一个联合体数据结构:
typedef unsigned long uint32;
typedef unsigned short uint16;
typedef unsigned char uint8;

typedef union foo_u_ {
uint32 member1;
uint16 member2[2];
uint8 member3[4];
} foo_u;

那么,当这个联合体中,member1的值为0x12345678的时候,member2[0]和member3[0]各为多少呢?

因为不同体系结构的处理器,不同的编译器对各种类型所占的字节数也有不同,现假设上面的unsigned long占4个字节也就是32位,unsigned short占2个字节也就是16位,unsigned char占1个字节也就是8位。

我们知道联合体变量的存储方式,它会按照联合体中占字节数最大的那个类型来开辟内存,不是像结构体中为每个成员变量都分配一定的内存空间。在联合体中其他的成员变量都会重复的存放在大类型成员变量的内存上。所以一个成员变量值的改变会影响到其他成员变量。

上面的联合体变量中的成员变量,所占内存最大的就是占32位的member1(其实另外两个成员变量也是32位)所以这里就会给这个联合体变量分配4个字节也就是32位的存储空间,假如首地址为0x0012ff78,则按照小端模式,在内存中排放的顺序为:

地址:78 79 7a 7b

数据:785634 12

而对于第二个成员变量数组,含有两个数组元素,每个数组元素占16位,而且地址也是从第一个成员变量起始地址开始,所以member2[0]就是0x5678,而member2[1]也就是0x1234,而对于第三个成员变量数组含有4个数组元素,member3[0]就是0x78,代表的字符为x

member3[1]也就是0x56,代表字符为V,member3[2]也就是0x34,代表字符为4,member3[3]是0x12代表着一个小黑块。

而对于大端模式,联合体中第二,第三个成员变量的值就会变化。

分享到:
评论

相关推荐

    Sybase ASE 15.7 开发文档:系统管理指南(卷二)

    目标体系结构 .......... 108 内核模式 .......... 112 切换内核模式 .......... 113 任务 .......... 114 使用线程运行任务 .......... 114 配置 SMP 环境 .......... 115 线程池 .......... 115 管理引擎 ...........

    计算机科学丛书:计算机组成原理 [英] 艾伦·克莱门茨(Alan Clements)(2017.3出版)

    书中围绕基本概念、指令集体系结构、处理器组成和能效、存储与外设以及处理器级并行等五个核心问题将这些内容有条不紊地组织在一起,以便满足不同专业的教学需要。 中文版引进的时候综合考虑国内高校“计算机组成与...

    x86 x64体系探索及编程part1

    271 11.2.4 页转换表资源 272 11.3 32 位paging 模式(non-PAE 模式) 273 11.3.1 CR3 结构 274 11.3.2 32 位paging 模式下的PDE 结构 275 11.3.3 使用32 位paging 279 11.4 PAE paging 模式. 282 11.4.1 在Intel64 ...

    x86 x64体系探索及编程 part2

    271 11.2.4 页转换表资源 272 11.3 32 位paging 模式(non-PAE 模式) 273 11.3.1 CR3 结构 274 11.3.2 32 位paging 模式下的PDE 结构 275 11.3.3 使用32 位paging 279 11.4 PAE paging 模式. 282 11.4.1 在Intel64 ...

    x86 x64体系探索及编程part4

    271 11.2.4 页转换表资源 272 11.3 32 位paging 模式(non-PAE 模式) 273 11.3.1 CR3 结构 274 11.3.2 32 位paging 模式下的PDE 结构 275 11.3.3 使用32 位paging 279 11.4 PAE paging 模式. 282 11.4.1 在Intel64 ...

    x86 x64体系探索及编程part3

    271 11.2.4 页转换表资源 272 11.3 32 位paging 模式(non-PAE 模式) 273 11.3.1 CR3 结构 274 11.3.2 32 位paging 模式下的PDE 结构 275 11.3.3 使用32 位paging 279 11.4 PAE paging 模式. 282 11.4.1 在Intel64 ...

    IIS总线的嵌入式音频系统设计.pdf

    音频系统设计包括软件设计和硬件设计两方面,在硬件上使用了基于IIS总线的音频系统体系结构。 IIS(Inter-IC Sound bus)是菲利浦公司提出的串行数字音频总线协议。目前很多音频芯片和MCU都提供了对IIS的支持。在...

Global site tag (gtag.js) - Google Analytics