ARM存储格式的“大小端”解析,原来是这样!

arm储存—大端格式和小端格式 所谓的大端模式,是指数据的高位,保存在内存的低地址中,而数据的低位,保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放。
所谓的小端模式,是指数据的高位保存在内存的高地址中,而数 据的低位保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低,和我们的逻辑方法一致。
arm储存—大端小端的故事: 端模式(endian)的这个词出自jonathan swift书写的《格列佛游记》。这本书根据将鸡蛋敲开的方法不同将所有的人分为两类,从圆头开始将鸡蛋敲开的人被归为big endian,从尖头开始将鸡蛋敲开的人被归为littile endian。小人国的内战就源于吃鸡蛋时是究竟从大头(big-endian)敲开还是从小头(little-endian)敲开。在计算机业big endian和little endian也几乎引起一场战争。
我们知道在内存中数据是以字节为单位进行存储的,每个地址单元对应着一个字节(byte),一个字节为8位(bite)。但是很多时候数据除了8bit额char外,还有16bit的short,32位的long型(要看具体的编译器),必然存在多字节安排的问题。不同的计算机存放多字节值的顺序不同,有些机器在起始地址存放低位字节(低位先存),即小端模式;有的机器在起始地址存放高位字节(高位先存),即大端模式。基于intel的cpu,采用的是低位先存。而keil c51则为大端模式。大端小端对应着数据在存储器中的存放顺序。
同时,在网络传输中,网络协议需要指定网络字节顺序,tcp/ip协议中使用16位整数和32位整数的高位先存模式,对应我们的大端模式。
下面是两个具体例子:
16bit宽的数0x1234在little-endian模式(以及big-endian模式)cpu内存中的存放方式(假设从地址0x4000开始存放)为:
32bit宽的数0x12345678在little-endian模式以及big-endian模式)cpu内存中的存放方式(假设从地址0x4000开始存放)为:
联合体union的存放顺序是所有成员都从低地址开始存放,利用该特性可以轻松地获得了cpu对内存采用little-endian还是big-endian模式读写。
写程序判断处理器是little-endian模式,还是big-endian模式,可以通过以下程序:
1、通过将int强制类型转换成char单字节,通过判断起始存储位置。
1 void main(int argc, char **argv)
2 {
3 int i = 1;
4 char *cp = (char *)&i; //前面是指针运算符*,前值类型转换。后面是取地址符号。
5 if (*cp) //如果此时cp指向的内存为1的话,则为小端,否则为大端。
6 printf(“little endian\n”);
7 else
8 printf(“big endian\n”);
9
10 exit(exit_success);
11 }
注释:如果小端方式中(i占至少两个字节的长度)则i所分配的内存最小地址那个字节中就存着1,其他字节是0.大端的话则1在i的最高地址字节处存放,char是一个字节,所以强制将char型量p指向i则p指向的一定是i的最低地址,那么就可以判断p中的值是不是1(或者为0,也即是假)来确定是不是小端。
或者如下程序:
void main()
{
short int x;
char x0,x1;
x=0x1122;
x0=((char*)&x)[0]; //低地址单元
x1=((char*)&x)[1]; //高地址单元
if (0x11 == x0 && 0x22 == x1)
{
cout 《《 “big_endian” 《《 endl;
}
else
{
cout 《《 “little_endian” 《《 endl;
}
}
2、利用联合体union的存放顺序是所有成员都从低地址开始存放,判断处理器模式。
bool checkcpu( )
{
{
union w
{
int a;
char b;
} c;
c.a = 1;
return(c.b ==1);
}
}
以及如下程序:
bool islittleendian()
{
union _dword
{
int all;
struct _bytes
{
char byte0;
char pad[3];
}bytes;
}dword;
dword.all=0x87654321;
return (0x21==dword.bytes.byte0);
}
分析:如果你的处理器调用函数islittleendian返回1,那么说明你的处理器为little endian,否则为big endian.注意,如果在little endian处理器上,byte0和pad按内存从低到高的存放顺序:low-》byte0 pad[0] pad[1] pad[2] -》high;0x87654321按内存从低到高的存放顺序: 0x21 0x43 0x65 0x87, 可见byte0对应到0x21。所以通过判断dword中第一个字节dword.bytes.byte0是否与0x21相等就可以看出是否是little endian。

无线和TVB的区别
FCC正在更新基础设施政策,并鼓励私营企业投资 5G网络
关于FPGA芯片的故事,你知道多少呢?
光学生物传感器的具体应用及原理介绍
BUCK芯片外围的电阻是用来干什么的
ARM存储格式的“大小端”解析,原来是这样!
日本知名的元器件大厂,在目前的市场环境下,好像有点“慌”!
VR+教育是否行得通?博士们是这么认为的
基于一个超快速可扩展和去中心化的区块链网络IOST介绍
AI芯片的未来需要依靠什么
节能补贴新政拉动平板产业良性发展
U盘的写入数据传输率
希捷于2026年推出50TB机械硬盘,将采用新技术
华为发布声明对5G的进展情况进行了回应和澄清
锂电池储能系统的用途和意义
激光焊接机焊接3mm锰钢的工艺特点
嵌入式系统中非易失、不可复位计数器的实现
蒸汽计量系统的组成结构
功率放大器在压电致动器开环实验特性研究中的应用
保护薄膜表面瑕疵检测系统的原理及特点