关于CPU字节存放顺序的说明(大端小端)

本文介绍了端模式(Big-Endian与Little-Endian)的概念及其在计算机存储中的应用,并提供了判断处理器采用哪种端模式的方法。

      端模式(Endian)的这个词出自Jonathan Swift书写的《格列佛游记》。这本书根据将鸡蛋敲开的方法不同将所有的人分为两类,从圆头开始将鸡蛋敲开的人被归为Big Endian,从尖头开始将鸡蛋敲开的人被归为Littile Endian。小人国的内战就源于吃鸡蛋时是究竟从大头(Big-Endian)敲开还是从小头(Little-Endian)敲开。在计算机业Big Endian和Little Endian也几乎引起一场战争。在计算机业界,Endian表示数据在存储器中的存放顺序。下文举例说明在计算机中大小端模式的区别。

如果将一个32位的整数0x12345678存放到一个整型变量(int)中,这个整型变量采用大端或者小端模式在内存中的存储由下表所示。为简单起见,本书使用OP0表示一个32位数据的最高字节MSB(Most Significant Byte),使用OP3表示一个32位数据最低字节LSB(Least Significant Byte)。

 

 

 

地址偏移

大端模式

小端模式

0x00

12(OP0)

78(OP3)

0x01

34(OP1)

56(OP2)

0x02

56(OP2)

34(OP1)

0x03

78(OP3)

12(OP0)

 

 

如果将一个16位的整数0x1234存放到一个短整型变量(short)中。这个短整型变量在内存中的存储在大小端模式由下表所示。

 

 

 

地址偏移

大端模式

小端模式

0x00

12(OP0)

34(OP1)

0x01

34(OP1)

12(OP0)

 

 

由上表所知,采用大小模式对数据进行存放的主要区别在于在存放的字节顺序,大端方式将高位存放在低地址,小端方式将低位存放在低地址。采用大端方式进行数据存放符合人类的正常思维,而采用小端方式进行数据存放利于计算机处理。到目前为止,采用大端或者小端进行数据存放,其孰优孰劣也没有定论。(小端是低位先存,大端高位先存)

有的处理器系统采用了小端方式进行数据存放,如Intel的奔腾。有的处理器系统采用了大端方式进行数据存放,如IBM半导体和Freescale的PowerPC处理器。不仅对于处理器,一些外设的设计中也存在着使用大端或者小端进行数据存放的选择。

因此在一个处理器系统中,有可能存在大端和小端模式同时存在的现象。这一现象为系统的软硬件设计带来了不小的麻烦,这要求系统设计工程师,必须深入理解大端和小端模式的差别。大端与小端模式的差别体现在一个处理器的寄存器,指令集,系统总线等各个层次中。

 

 

判断大端小端

int i=1;  
    char *p=(char *)&i;  
    if(*p==1)    
           printf("1"); 
    else
           printf("2");

      大小端存储问题,如果小端方式中(i占至少两个字节的长度)则i所分配的内存最小地址那个字节中就存着1,其他字节是0(00000001).大端的话则1在i的最高地址字节处存放,char是一个字节,所以强制将char型量p指向i则p指向的一定是i的最低地址,那么就可以判断p中的值是不是1来确定是不是小端。

 

利用共同体低位先存的特性,判断大端小端。
int checkCPU( )
{
    {
           union w
           {  
                  int a;
                  char b;
           } c;
           c.a = 1;
           return(c.b ==1);
/*return 1小端先存,return 0大端先存*/
    }
}
剖析:
嵌入式系统开发者应该对Little-endian和Big-endian模式非常了解。采用Little-endian模式的CPU对操作数的存放方式是从低字节到高字节,而Big-endian模式对操作数的存放方式是从高字节到低字节。例如,16bit宽的数0x1234在Little-endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)为:
内存地址
0x4000
0x4001
存放内容
0x34
0x12
而在Big-endian模式CPU内存中的存放方式则为:
内存地址
0x4000
0x4001
存放内容
0x12
0x34
32bit宽的数0x12345678Little-endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)为:
内存地址
0x4000
0x4001
0x4002
0x4003
存放内容
0x78
0x56
0x34
0x12
而在Big-endian模式CPU内存中的存放方式则为:
内存地址
0x4000
0x4001
0x4002
0x4003
存放内容
0x12
0x34
0x56
0x78
联合体union的存放顺序是所有成员都从低地址开始存放,面试者的解答利用该特性,轻松地获得了CPU对内存采用Little-endian还是Big-endian模式读写。如果谁能当场给出这个解答,那简直就是一个天才的程序员。
### 大端与小字节序概念 在计算机科学中,数据存储方式分为两种主要的字节顺序大端(Big-Endian)和小(Little-Endian)。对于多字节数值而言,在内存中的表示方法决定了其高位字节低位字节的位置。 #### 小模式定义 采用小模式时,最低有效位被存放在最小地址处;而最高有效位则位于最大地址位置。这种布局使得数值按照从低到高的次序依次排列于连续的空间之中[^1]。 #### 大端模式定义 相反地,在大端模式下,最高有效位会先被放置在起始(即较小)地址上,接着才是后续较低的有效部分跟随在其后面。因此当读取一个多字节数值时,最先遇到的是它的最左边或者说是最重要的那一位。 ### 区别及特点对比 | 特征/类型 | Big Endian (BE) | Little Endian (LE) | |-----------|-----------------------------------------|------------------------------------------| | 地址 | 高位字节存于低地址 | 低位字节存于低地址 | | 排列顺序 | 数据按从左至右、由高到底的方式储存 | 数据按从右往左、自底向上的形式保存 | | 可视化 | 更接近人类习惯书写多位数 | 符合CPU处理流程 | ### 应用场景分析 网络协议通常规定使用统一的大端格式来传输信息包,这有助于不同架构间的互操作性和标准化通信过程。例如TCP/IP栈就遵循此原则以确保跨平台兼容性。 另一方面,许多现代处理器内部运算倾向于利用小结构优化性能表现,因为它们能够更方便地访问单个字节并执行算术逻辑单元(ALU)指令集。Intel x86系列就是典型的例子之一。 ```cpp // C++代码示例展示如何判断当系统的字节序 #include <iostream> bool is_little_endian() { union { uint32_t i; char c[4]; } b = {0x01020304}; return b.c[0] == 4; // 如果第一个字节是04,则为little endian } int main(){ std::cout << (is_little_endian()? "Little":"Big") << "-endian system\n"; } ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值