深入浅出大端和小端
大端序与小端序
⼤端序与⼩端序端序(Endianness),⼜称字节序、尾序、位序。
在计算机领域是指机器存放多字节数据的字节顺序。
在涉及到低层数据存储和⽹络数据传输研究中都会涉及端序。
⼤端序(Big-Endian,⼤尾序):⾼位字节放在内存的低地址,低位字节放在内存的⾼地址。
⼩端序(Little-Endian,⼩尾序):低位字节放在内存的低地址,⾼位字节放在内存的⾼地址。
端序是与硬件的体系结构相关⽽与所使⽤的操作系统⽆关的概念,⽬前基本上所有x86系列的PC机都是⼩端序。
在32位机器上,对于数0x12345678来说,低层表⽰的⽅法因端序⽽排列不同⼩端序: | 0x78 | 0x56 | 0x34 | 0x12 |低地址 --0----------7-8-------15-16------23-24-------31--> ⾼地址⼤端序: | 0x12 | 0x34 | 0x56 | 0x78 |低地址 --0----------7-8-------15-16------23-24-------31--> ⾼地址判定⽅法:⽅法⼀:将整形int强制转换char测试1bool isBigEndian()2 {3int a = 1;4if (((char*)&a)[sizeof(int) - 1] == 1) {5return true;6 } else {7return false;8 }9 }对于32位机器来说:⼩端序: | 0x01 | 0x00 | 0x00 | 0x00 |低地址 --0---[0]---7-8--[1]--15-16-[2]-23-24--[3]--31--> ⾼地址⼤端序: | 0x00 | 0x00 | 0x00 | 0x01 |低地址 --0---[0]---7-8--[1]--15-16-[2]-23-24--[3]--31--> ⾼地址⽅法⼆:使⽤union,其所有成员共享同⼀个最⼤的内存地址。
轻松记住大端小端的含义(附对大端和小端的解释)
轻松记住⼤端⼩端的含义(附对⼤端和⼩端的解释) 或许你曾经仔细了解过什么是⼤端⼩端,也动⼿编写了测试⼿头上的机器上是⼤端还是⼩端的程序,甚⾄还编写了⼤端⼩端转换程序;但过了⼀段时间之后,当你再看到⼤端和⼩端这两个字眼,你的脑中很快浮起了⾃⼰曾经做过的⼯作,却总是想不起究竟哪种是⼤端、哪种是⼩端,然后⼜去查以前写的记录?更让⼈不快的是,这种经历反反复复,让你⼗分困扰。
如果你和以前的笔者⼀样,有过这种不快的经历,那么这篇⽂章希望能帮你彻底解决这个苦恼,让你彻底记住它们。
如果你在⼯作中经常使⽤到⼤端和⼩端以⾄于对它们⼗分熟悉,或者你的记忆⼒在保持时间的长度和精准度上都⼗分优秀,以⾄于不需要借助其他的⽅法,那么这篇⽂章不适合你。
如果你在看这篇⽂章前完全不知道什么是⼤端和⼩端,那么可以参考本⽂的附录或者其他的博⽂,相关的介绍⾮常之多,⽽附录提供了⼀个很常见解释和⼀段测试程序,然后再来看正⽂。
为了帮助记忆,理解是必要的;⽽记忆的⽬的,也就是为什么要记住它,是更重要的。
或许你会问,先了解概念,⽤的时候再查,不⾏么?其实我之前也是这么认为的。
⼤端和⼩端这两个名词,你会在很多有关⽹络编程、系统设计、甚⾄是代码写作的书上看到,⽽且它也是很多公司的笔试题、⾯试题热门内容,可见它在⼀些领域是很常⽤。
如果等到你⽤的时候再查,⼀⽅⾯要降低你的⼯作效率,另⼀⽅⾯,应试的时候也不是你想查就能查的;其实最主要的是,在掌握规律后,记住它们并不困难。
现在先来理解这对概念,⼤端和⼩端这两个令⼈迷惑的术语究竟是如何产⽣的?《程序设计实践》第9章中提到,“⼤端”和“⼩端”可以追溯到1726年的Jonathan Swift的《格列佛游记》,其中⼀篇讲到有两个国家因为吃鸡蛋究竟是先打破较⼤的⼀端还是先打破较⼩的⼀端⽽争执不休,甚⾄爆发了战争。
1981年10⽉,Danny Cohen的⽂章《论圣战以及对和平的祈祷》(On holy wars and a plea for peace)将这⼀对词语引⼊了计算机界。
字节序,大端,小端的概念
字节序,大端,小端的概念大端、小端:大小端是指CPU存储数据的方式,比如一个0x01020304这个整数,在WIN、Linux下在内存中的布局如下[01][02][03][04] 注意左边是高地址,而右边是低地址在UNIX下则是[04][03][02][01] 注意左边是高地址,而右边是低地址通俗的说,和WIN下的内存布局一致的就是小端,和UNIX下一致的就是大端。
其实在以前还出现过中端的的机型,不过这些机型也太“孤僻”了,已经落伍没人生产没人用了。
网络字节序:其实是指网络传输的字节序,这个字节序可能是大端序或者小端序,这取决于软件开始时通讯双方的协议规定。
平时,如果有人说的网络字节序,那么大家就认为是大端序。
主机字节序:是指主机处理数据时采用的字节序,虽然主机字节序和网络字节序是相对的概念,但是我们说主机字节序的时候,并不默认是之大端或者小端,而是结合机型来确定大小端的。
位序:我们通常所说的字节序是指字节之间的关系,但是即使是一个字节中的某一位(bit)也是有排序的问题的。
位序也有大端序,小端序,中端序,也还有其他的乱七八糟的位序的,但是都不常见。
开发的时候,我们是不用关心位序,编译器和CPU会自己处理这些事情。
算术运算与内存操作运算:算术运算是不改变被运算数据的字节序的,此时我们不用关心所操作的数据到底是什么字节序的。
但是内存操作运算就要注意了,比若我们将一个整数指针强制转换为一个字符指针类型,然后对字符指针类型的四个字节进行算数运算,此时我们必须知道是什么字节序。
不然写出的代码要么是错误的,要么移植到其他机器的时候就不能正常运行。
常见的算术有+ - * / % & | ~ << >> = 等,请注意& | ~ << >> 这几个是算术运算而不是内存操作运算,所以他们进行混合运算的时候不用关心字节序或者位序问题。
赋值运算符仅在数据类型兼容的时候才不涉及字节序问题,才能算作算术运算。
大端模式和小端模式
⼤端模式和⼩端模式1.为什么存在⼤⼩端模式计算机系统中,每个地址单元对应⼀个字节(8bit),⼀种数据类型的数据可能占⽤若⼲字节。
如何安排这种数据类型中的各个字节,哪个字节在低地址哪个在⾼地址,以及⼀个字节中的各个⽐特的排列,这就牵涉到⼤⼩端模式。
也就是⼤家常说的字节序和⽐特序问题。
字节序和⽐特序⼀般是⼀致的,要么都是⼤端,要么都是⼩端。
2.什么是⼤端和⼩端⼤端模式:低位(字节/⽐特)放在⾼地址中,⾼位(字节/⽐特)放在低地址中。
⼩端模式:低位(字节/⽐特)放在低地址中,⾼位(字节/⽐特)放在⾼地址中。
⾼位和地位是对于我们正常阅读和书写来说,最开始是⾼位,例如int型数0x1234,0x12是字节的⾼位,0x34是字节的低位。
根据以上规则,我们给出在⼤、⼩端序系统中整数0x0a0b0c0d的表⽰⽅式。
对于⼤端系统:byte addr 0 1 2 3bit offset 01234567 01234567 01234567 01234567binary 00001010 00001011 00001100 00001101hex 0a 0b 0c 0d对于⼩端系统:byte addr 3 2 1 0bit offset 76543210 76543210 76543210 76543210binary 00001010 00001011 00001100 00001101hex 0a 0b 0c 0d3. 检测⼤⼩端联合体的存放顺序是所有成员都从低地址开始存放,利⽤该特性可以轻松获得当前系统采⽤⼤端还是⼩端模式BOOL IsBigEndian(){union NUM{int a;char b;}num;num.a = 0x1234;if( num.b == 0x12 ){return TRUE;}return FALSE;}4.常见的⼤⼩端⼀般操作系统都是⼩端模式;⽽通讯协议是⼤端模式;java和平台⽆关,默认是⼤端模式常见的cpu的⼤⼩端:⼤端:PowerPC、IBM、Sun⼩端:x86ARM既可以⼯作在⼤端模式,也可以⼯作在⼩端模式。
大端模式与小端模式理解
⼤端模式与⼩端模式理解字节序字节序指多字节数据在计算机内存储或者⽹络上传输时各字节的顺序。
(来源:百度百科)为了⽅便,逻辑上将字节序列⾥左边的字节称为⾼字节,右边的字节称为低字节,从左到右,由⾼到低,这样符合数学上的思维习惯,左边是⾼位,右边是地位。
⼤端模式与⼩端模式由于每个字节在内存中都是有地址的,并且内存的地址是顺序排列的,当我们在内存中保存数据时:如果,⾼字节存放在低地址,低字节存放在⾼地址,则为⼤端模式(big-endian)。
如果,低字节存放在低地址,⾼字节存放在⾼地址,则为⼩端模式(little-endian)。
数据从内存保存到⽂件(或发送到⽹络上)时,会受到内存的⼤端模式与⼩端模式的影响。
数据从⽂件读取到(或从⽹络接收到)内存时,需要知道之前是先保存的(或是先发送的)⾼字节还是低字节。
C++⽰例代码1//int 占 4 个字节,short 占 2 个字节int main(){printf("在栈上分配内存\n");int a = 0x11223344;short b = 0x5566;short c = 0x7788;unsigned char *pa = (unsigned char *)&a;unsigned char *pb = (unsigned char *)&b;unsigned char *pc = (unsigned char *)&c;printf("pa 0x%p 0x%x\n", pa, a);printf("pb 0x%p 0x%x\n", pb, b);printf("pc 0x%p 0x%x\n", pc, c);printf("按字节序打印所有字节(⾼字节->低字节)\n");printf("a0 0x%x\n", (a & 0xFF000000) >> (3 * 8));printf("a1 0x%x\n", (a & 0x00FF0000) >> (2 * 8));printf("a2 0x%x\n", (a & 0x0000FF00) >> (1 * 8));printf("a3 0x%x\n", (a & 0x000000FF));printf("b0 0x%x\n", (b & 0xFF00) >> (1 * 8));printf("b1 0x%x\n", (b & 0x00FF));printf("c0 0x%x\n", (c & 0xFF00) >> (1 * 8));printf("c1 0x%x\n", (c & 0x00FF));printf("根据地址顺序打印所有字节(低地址->⾼地址)\n");for (int i = 0; i < 4; i++) {printf("pa[%d] 0x%p 0x%02x\n", i, pa + i, pa[i]);}for (int i = 0; i < 2; i++) {printf("pb[%d] 0x%p 0x%02x\n", i, pb + i, pb[i]);}for (int i = 0; i < 2; i++) {printf("pc[%d] 0x%p 0x%02x\n", i, pc + i, pc[i]);}return 0;}⽰例代码1运⾏结果在栈上分配内存pa 0x007ffe24 0x11223344pb 0x007ffe22 0x5566pc 0x007ffe20 0x7788按字节序打印所有字节(⾼字节->低字节)a0 0x11a1 0x22a2 0x33a3 0x44b0 0x55b1 0x66c0 0x77c1 0x88根据地址顺序打印所有字节(低地址->⾼地址)pa[0] 0x007ffe24 0x44pa[1] 0x007ffe25 0x33pa[2] 0x007ffe26 0x22pb[0] 0x007ffe22 0x66pb[1] 0x007ffe23 0x55pc[0] 0x007ffe20 0x88pc[1] 0x007ffe21 0x77⽰例代码1结果分析a、b、c 在内存中的排列情况:---------------------------------------------------|低地址 -> ⾼地址|---------------------------------------------------|....|0x88|0x77|0x66|0x55|0x44|0x33|0x22|0x11|....|---------------------------------------------------a、b、c 是在栈中分配的,可以看到内存地址是连续的,且 a 的地址相对较⾼,c 的地址相对较低。
什么是大小端,程序如何判断大小端?如何判断所使用系统的字节序?
什么是⼤⼩端,程序如何判断⼤⼩端?如何判断所使⽤系统的字节序?假设计算机要存储4byte int a = 0x12345678, 通常有2种存储⽅式: ⼤端, 和⼩端. 具体是哪种, 取决于计算机体系结构(硬件)字节地址(序号)0123低->⾼⼤端12345678⼩端78563412上⾯表格都以16进制表⽰, 省略了"0x".判断依据:⼤端: 低字节存储⾼位字节数据, 如序号为0的地址存储了⾼位字节12;⼩端: 低字节存储低位字节数据, 如序号为0的地址存储了低位字节78;注: a按数值的意义, 从⾼位字节到低位字节, 分别是: 12, 34, 56, 78程序判断⽅法(3种):#include <stdio.h>#include <stdint.h>typedef union {uint16_t v;uint8_t bytes[2]; // bytes[0] 是⼩地址,bytes[1]是⼤地址:w}u16;/* ⽅法1: 利⽤联合体进⾏取不同地址对应数* 利⽤联合体, 对2byte 联合体赋值后, 分别检查⾼低地址字节数据是否为⼤端特征* */void isBigEnding() {u16 a;a.v = 0x1234;if (a.bytes[0] == 0x12 && a.bytes[1] == 0x34) {printf("big ending\n");}else if (a.bytes[0] == 0x34 && a.bytes[1] == 0x12) {printf("little ending\n");}else {printf("error value");}return;}#include <arpa/inet.h>/* ⽅法2: 利⽤已知端序的API, 进⾏⽐较* 利⽤已知的⽹络序为⼤端, ⽽htons是将2byte主机序数据转换成⽹络序, 判断转换前后是否有变化* 如果没变化, 则说明为⼤端; 如果有, 则说明为⼩端* */void isBigEnding2() {uint16_t hport = 0x8000;uint16_t nport = htons(hport); // ⽹络字节序是⼤端printf("number in net byte order is 0x%x\n", nport );if (hport == nport) {printf("big ending\n");}else {printf("little ending\n");}}/** ⽅法3:取地址直接转换*/void isBigEnding3() {uint16_t n = 0x1234;if ( *(uint8_t *)&n == 0x12) {printf("big ending\n");}else if (*(uint8_t *)&n == 0x34) {printf("little ending\n");}else {printf("error value");}}/* 写⼀个程序判断所使⽤系统的字节序 */ int main() {isBigEnding();isBigEnding2();isBigEnding3();return0;}。
结构体大小端定义
结构体大小端定义大小端(Endian)是计算机存储数据的一种方式,它决定了数据在内存中的存储顺序。
在计算机系统中,数据在内存中的存储是以字节为单位的,每个字节有一个唯一的地址。
在存储多字节的数据时,计算机可以选择不同的字节存储顺序,即大小端。
大小端定义了数据的高位字节和低位字节的存储顺序。
在小端存储方式中,数据的低位字节(最小有效位)存储在低地址中,而高位字节(最高有效位)存储在高地址中。
而在大端存储方式中,数据的高位字节存储在低地址中,低位字节存储在高地址中。
为了更好地理解大小端的概念,我们可以以一个结构体的存储为例。
假设我们有一个结构体定义如下:```cstruct example {int a;char b;short c;};```在内存中,这个结构体的存储空间是连续的。
根据大小端的不同,这个结构体的存储方式也会有所区别。
在小端存储方式中,结构体的存储顺序如下:```地址内容0x1000 a的低字节0x1001 a的高字节0x1002 b0x1003 c的低字节0x1004 c的高字节```可以看到,结构体的成员变量按照从低地址到高地址的顺序依次存储。
这是因为小端存储方式将数据的低位字节存储在低地址中,高位字节存储在高地址中。
相反,在大端存储方式中,结构体的存储顺序如下:```地址内容0x1000 a的高字节0x1001 a的低字节0x1002 b0x1003 c的高字节0x1004 c的低字节```可以看到,结构体的成员变量按照从高地址到低地址的顺序依次存储。
这是因为大端存储方式将数据的高位字节存储在低地址中,低位字节存储在高地址中。
在实际应用中,大小端的选择对于数据的传输和解析非常重要。
在网络通信中,不同的计算机可能使用不同的大小端存储方式。
因此,在进行网络数据传输时,需要对数据进行大小端的转换,以保证数据的正确解析。
在编程语言中,通常提供了一些函数或宏来进行大小端的转换。
例如,在C语言中,可以使用`htonl`和`ntohl`函数来进行32位整型数据的大小端转换。
什么是大端模式,和小端模式
熟练掌握网络字节序的转换
大端转换
当主机A要把数据发送到主机B时,主机A需要把本机的字节 序转换为网络字节序后才能发送。
小端转换
当主机A收到从主机B发送的数据时,主机A需要把网络字节 序转换为本机的字节序后才能处理。
THANKS
感谢观看
模式。
06
大端模式和小端模式对我们 的启示
深入了解计算机存储机制
大端模式一种数据存储方式,其中高位字节保存在内存的低 地址中,而低位字节保存在内存的高地址中。这种存储方式 在机器字长为16位或32位时比较常见,但现在几乎所有的计 算机都是小端模式。
小端模式一种数据存储方式,其中低位字节保存在内存的低 地址中,而高位字节保存在内存的高地址中。这种存储方式 在机器字长为16位或32位时比较常见,但现在几乎所有的计 算机都是小端模式。
什么是大端模式,和小端模 式
xx年xx月xx日
目 录
• 引言 • 大端模式 • 小端模式 • 大端模式和小端模式的差异 • 大端模式和小端模式的判断方法 • 大端模式和小端模式对我们的启示
01
引言
什么是端模式
• 端模式(Endianness)是指计算机系统在处理字节顺序的方 式,也就是多字节数据在内存中如何排列。
存储顺序
在内存中存储数据时,大端模式将数据的每个字节按照由高到低的顺序存储,以 实现数据的正确表示。
大端模式的应用场景
网络通信
在网络通信中,数据的传输通 常是按照大端模式进行的,因 此需要将数据进行字节序的转 换,以确保接收和发送两端的
数据一致性。
文件存储
在某些文件格式中,如网络协 议中的数据包格式,需要按照 大端模式来读取和解析数据。
小端模式的原理
大端和小端(BigendianandLittleendian)
⼤端和⼩端(BigendianandLittleendian)⼀、⼤端和⼩端的问题对于整型、长整型等数据类型,Big endian 认为第⼀个字节是最⾼位字节(按照从低地址到⾼地址的顺序存放数据的⾼位字节到低位字节);⽽ Little endian 则相反,它认为第⼀个字节是最低位字节(按照从低地址到⾼地址的顺序存放据的低位字节到⾼位字节)。
例如,假设从内存地址 0x0000 开始有以下数据:0x0000 0x0001 0x0002 0x00030x12 0x34 0xab 0xcd如果我们去读取⼀个地址为 0x0000 的四个字节变量,若字节序为big-endian,则读出结果为0x1234abcd;若字节序为little-endian,则读出结果为0xcdab3412。
如果我们将0x1234abcd 写⼊到以 0x0000 开始的内存中,则Little endian 和 Big endian 模式的存放结果如下:地址 0x0000 0x0001 0x0002 0x0003big-endian 0x12 0x34 0xab 0xcdlittle-endian 0xcd 0xab 0x34 0x12⼀般来说,x86 系列 CPU 都是 little-endian 的字节序,PowerPC 通常是 big-endian,⽹络字节顺序也是 big-endian还有的CPU 能通过跳线来设置 CPU ⼯作于 Little endian 还是 Big endian 模式。
对于0x12345678的存储:⼩端模式:(从低字节到⾼字节)地位地址 0x78 0x56 0x34 0x12 ⾼位地址⼤端模式:(从⾼字节到低字节)地位地址 0x12 0x34 0x56 0x78 ⾼位地址⼆、⼤端⼩端转换⽅法htonl() htons() 从主机字节顺序转换成⽹络字节顺序ntohl() ntohs() 从⽹络字节顺序转换为主机字节顺序Big-Endian转换成Little-Endian#define BigtoLittle16(A) ((((uint16)(A) & 0xff00) >> 8) | (((uint16)(A) & 0x00ff) << 8))#define BigtoLittle32(A) ((((uint32)(A) & 0xff000000) >> 24) | (((uint32)(A) & 0x00ff0000) >> 8) | \(((uint32)(A) & 0x0000ff00) << 8) | (((uint32)(A) & 0x000000ff) << 24))三、⼤端⼩端检测⽅法如何检查处理器是big-endian还是little-endian?C程序:int i = 1;char *p = (char *)&i;if(*p == 1)printf("Little Endian");elseprintf("Big Endian");⼤⼩端存储问题,如果⼩端⽅式中(i占⾄少两个字节的长度)则i所分配的内存最⼩地址那个字节中就存着1,其他字节是0.⼤端的话则1在i的最⾼地址字节处存放,char是⼀个字节,所以强制将char型量p指向i则p指向的⼀定是i的最低地址,那么就可以判断p中的值是不是1来确定是不是⼩端。
大端和小端概念、区别、转换以及辨别方法解析
大端和小端概念、区别、转换以及辨别方法解析
大端和小端概念、区别、转换以及辨别方法解析
学习底层编程或逆向的童鞋,肯定对这两个名词并不陌生吧?!今天就给大家介绍一下这两个概念.
科普:
大端和小端,老外叫Big-Endian 和Little-Endian,其实指的都是同一个东东在计算机界,表示数据在存储器中的存放顺序。
不同的CPU、操作系统对待数据的存储方式各有不同,但一般常见的操作系统都是小端,而通讯协议则是大端。
但并不是说系统是小端形式存储,文件就一定要采用小端的形式,不同的应用程序对于自身数据的存储方式也各有千秋(自家数据爱咋放咋放,有些还打乱了加密呢),比如:
* Adobe PS -- 大端
* BMP -- 小端
* GIF -- 小端
* JPEG -- 大端
* MacPaint -- 大端
* RTF -- 小端
那么小端和大端有什么区别呢?举个栗子大家就明了了:
比如0x12345678 这个数:
* 大端法在内存中按字节依次存放为:12 34 56 78
* 小端法在内存中按字节依次存放为:78 56 34 12
解释:
大端:较高的有效字节存放在较低的存储器地址,较低的有效字节存放在较高的存储器地址。
比如整型变量0x12345678 占 4 个字节,那么根据内存地址从小到大它们的存放方式如下:。
大小端
大端模式所谓的大端模式,是指数据的低位(就是权值较小的后面那几位)保存在内存的高地址中,而数据的高位,保存在内存的低地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;小端模式所谓的小端模式,是指数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低,和我们的逻辑方法一致。
为什么有大小端模式之分为什么会有大小端模式之分呢?这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为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处理器还可以由硬件来选择是大端模式还是小端模式。
在各种计算机体系结构中,对于字节、字等的存储机制有所不同,因而引发了计算机通信领域中一个很重要的问题,即通信双方交流的信息单元(比特、字节、字、双字等等)应该以什么样的顺序进行传送。
如果不达成一致的规则,通信双方将无法进行正确的编/译码从而导致通信失败。
目前在各种体系的计算机中通常采用的字节存储机制主要有两种:big-edian和little-endian本文简要描述这两种存储机制的来历、特点和区别。
大端、小端与网络字节序
⼤端、⼩端与⽹络字节序⼤端(Big-Endian),⼩端(Little-Endian)以及⽹络字节序的概念在编程中经常会遇到,⽹络字节序(Network Byte Order)⼀般是指⼤端(Big-Endian,对⼤部分⽹络传输协议⽽⾔)传输,⼤端⼩端的概念是⾯向多字节数据类型的存储⽅式定义的,⼩端就是低位在前(低位字节存在内存低地址,字节⾼低顺序和内存⾼低地址顺序相同),⼤端就是⾼位在前,(其中“前”是指靠近内存低地址,存储在硬盘上就是先写那个字节)。
概念上字节序也叫主机序。
⼀、⼤⼩端概念1、⾸先⼤⼩端是⾯向多字节类型定义的,⽐如2字节、4字节、8字节整型、长整型、浮点型等,单字节的字符串⼀般不⽤考虑。
2、⼤端⼩端存储、传输、以及接收处理需要对应。
3、⼤端(Big-Endian)就是⾼字节(MSB)在前,内存存储体现上,数据的⾼位更加靠近低地址。
(低地址存⾼字节)4、⼩端(Little-Endian)就是低字节(LSB)在前,内存存储体现上,数据的低位更加靠近低地址。
(低地址存低字节)5、⽹络字节序⼀般是指⼤端传输。
⼆、⼤⼩端存储⽰例假设⼀个32位 unsigned int型数据0x12 34 56 78,⼤⼩端8位存储⽅式如下:⼤端存储⽅式为0x12 34 56 78⼩端存储⽅式为0x78 56 34 12,如下图。
三、常见CPU的⼤⼩端存储⽅式不同CPU有不同的字节序类型,典型的使⽤⼩端存储的CPU有:Intel x86和ARM典型的使⽤⼤端存储CPU有:Power PC、MIPS UNIX和HP-PA UNIX注:以上CPU需根据具体型号查询⼿册,有的CPU甚⾄可能同时能⽀持两种存储⽅式。
上⽂说的⽹络字节顺序则是表⽰⽹络传输时的字节序,按照TCP/IP协议是按照⼤端传输⽅式,也就是⾼字节先⾛(先传12,接着34,56,78),这跟本机存储和服务器存储没有关系,只要确保双⽅解析对应即可。
四、四个转换函数C/C++中有如下四个常⽤的转换函数,这四个函数在⼩端系统中⽣效,⼤端系统由于和⽹络字节序相同,所以⽆需转换。
数据存储与处理的字节序问题,大端和小端处理方式
数据存储与处理的字节序问题,大端和小端处理方式数据存储和处理的字节序问题对于计算机程序的性能和效率有着重要的影响。
在大多数情况下,数据的字节序应该与程序所使用的指令集和操作系统一致。
然而,在某些情况下,字节序可能需要进行调整,以优化性能和效率。
大端和小端处理方式是指在数据存储和处理过程中,对字节序进行调整的方式。
大端处理是指在数据存储过程中,将较大的数据值存储在较高的字节位置,较小的数据值存储在较低的字节位置。
这样可以使得计算机程序在读取和处理数据时能够更快地找到数据的位置,从而提高性能。
小端处理则是相反的过程,将数据值存储在较低的字节位置,较大的数据值存储在较高的字节位置。
下面是大端和小端处理的具体步骤:1. 大端处理:将较大的数据值存储在较高的字节位置,较小的数据值存储在较低的字节位置。
例如,在读取一个文件时,程序应该将文件的最大值存储在第一个字节位置,文件的最小值存储在最后一个字节位置。
2. 小端处理:将数据值存储在较低的字节位置,较大的数据值存储在较高的字节位置。
例如,在读取一个文件时,程序应该将文件的最大值存储在第二个字节位置,文件的最小值存储在第三个字节位置。
大端和小端处理可以应用于各种数据存储和处理场景,例如文件存储、数据库存储、网络数据传输等。
通过合理地应用大端和小端处理,可以提高计算机程序的性能和效率,使程序能够更快地响应用户的操作,更好地满足用户的需求。
除了大端和小端处理之外,还有一些其他的方式可以在数据存储和处理过程中调整字节序。
例如,可以使用字节交换算法,将一些数据值交换到另一个字节位置,以达到优化性能的目的。
还可以使用压缩算法,将数据值压缩成更小的数字,从而减少数据在存储和传输过程中的体积和重量。
在数据存储和处理过程中,字节序的优化是一个关键问题,能够影响到程序的性能和效率。
因此,需要合理地应用大端和小端处理以及其他的字节序调整方法,以优化程序的性能。
大端和小端有什么区别
大端和小端有什么区别
大端和小端的区别
一、大小端出现原因
计算机系统是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8bit。
但对于位数大于8位的处理器,如16位或32位
/64位的处理器,由于寄存器宽度大于一个字节,那么必然存在一个如何将多个字节安排的问题。
因此就导致了大端存储模式和小端存储模式的出现。
二、为什么会有小端字节序?
答案是,计算机电路先处理低位字节,效率比较高,因为计算都是从低位开始的。
所以,计算机的内部处理都是小端字节序。
但是,人类还是习惯读写大端字节序。
所以,除了计算机的内部处理,其他的场合几乎都是大端字节序,比如网络传输和文件储存。
三、
计算机硬件有两种储存数据的方式:大端字节序(bigendian)
和小端字节序(littleendian)。
举例来说,数值0x2211使用两个字节储存:高位字节是0x22,低位字节是0x11.
大端字节序:高位字节在前,低位字节在后,这是人类读写数值的方法。
小端字节序:低位字节在前,高位字节在后,即以0x1122形式
储存。
32位整数的求值公式也是一样的。
计算机的字节序 大端 小端
调用 test_show_bytes(12345)的输出结果如下图:
十进制 12345 的十六进制表示为 0x3039, 输出结果 39 30 00 00 是从 低位到高位依次打印出数据, 可以看出所使用的计算机字节序序使用的是(big endian)大端法
可以使用 c 代码来验证,下面的 c 程序实现把 int 类型数据各字节的值 依次打印出来
[cpp] view plaincopy
1. #include <stdio.h> 2. 3. typedef unsigned char *byte_pointer; 4. 5. void show_bytes(byte_pointer start,int len) 6. { 7. 8. 9. 10. 11. 12. 13. } 14. 15. void show_int(int x) 16. { 17. 18. } 19. 20. void test_show_bytes(int val) 21. { 22. 23. 24. } int ival = val; show_int(ival); show_bytes((byte_pointer)&x,sizeof(int)); } int i; for(i = 0; i < len; i++) { printf("%.2x",start[i]); printf("\n");
计算机的字节序“大端”和“小端”
分类: 计算机系统 2012-11-12 23:17 19 人阅读 评论(0) 收藏 编辑 删除 大端小端字节序
很多书籍中会提到“大端”和“小端”的说法。所谓“大端”和“小端”存储指的 是计算机中多于一个字节的数据在内存中的存放方式。 某些机器选择在 存储器中按照从最低有效字节到最高有效字节的顺序存储对象, 而另一 些机器则按照从最高有效字节到最低有效字节的顺序存储。 前一种规则 —最低有效字节在最前面的方式,称为小端法(little endian)。大多数 Intel 兼容机都采用这种规则。后一种规则—最高有效字节在最前面的 方式,称为大端法(big endian) 例如:一个 int 类型的值 0x12345678,在 32 位计算机中占 4 个字节。 假设其在内存中的地址为:0x101~0x103,那么大端法和小端法表示 分别为:
大端模式与小端模式、网络字节顺序与主机字节顺序
大端模式与小端模式、网络字节顺序与主机字节顺序1. 大端模式与小端模式1.1 概念及详解在各种体系的计算机中通常采用的字节存储机制主要有两种:big-endian和little-endian,即大端模式和小端模式。
先回顾两个关键词,MSB和LSB:MSB: Most Significant Bit ------- 最高有效位LSB:Least Significant Bit ------- 最低有效位1.1.1 大端模式(big-edian):MSB存放在最低端的地址上。
举例,假设双字节数0x1234以big-endian的方式存在起始地址0x00002000中:| data |<-- address| 0x12 |<-- 0x00002000| 0x34 |<-- 0x00002001在Big-Endian中,对于bit序列中的序号编排方式如下(以双字节数0x8B8A为例):bit | 0 1 2 3 4 5 6 7 | 8 9 10 11 12 13 14 15 |-----MSB-----------------------------------LSBval | 1 0 0 0 1 0 1 1 | 1 0 0 0 1 0 1 0 |+-----------------------------------------+= 0x8 B 8 A1.1.2 小端模式(little-endian):LSB存放在最低端的地址上。
举例,双字节数0x1234以little-endian的方式存在起始地址0x00002000中:| data |<-- address| 0x34 |<-- 0x00002000| 0x12 |<-- 0x00002001在Little-Endian中,对于bit序列中的序号编排和Big-Endian刚好相反,其方式如下(仍以双字节数0x8B8A为例):bit | 15 14 13 12 11 10 9 8 | 7 6 5 4 3 2 1 0 |-----MSB-----------------------------------LSBval | 1 0 0 0 1 0 1 1 | 1 0 0 0 1 0 1 0 |+-----------------------------------------+= 0x8 B 8 A1.2 数组在大端小端情况下的存储以unsigned int value = 0x12345678 为例,分别看看在两种字节序下其存储情况,我们可以用unsigned char buf[4]来表示value:Big-Endian: 低地址存放高位,如下:高地址---------------buf[3] (0x78) -- 低位buf[2] (0x56)buf[1] (0x34)buf[0] (0x12) -- 高位---------------低地址Little-Endian: 低地址存放低位,如下:高地址---------------buf[3] (0x12) -- 高位buf[2] (0x34)buf[1] (0x56)buf[0] (0x78) -- 低位--------------低地址1.3 大端小端转换方法Big-Endian转换成Little-Endian如下:#define BigtoLittle16(A) ((((uint16)(A) & 0xff00) >> 8) | \(((uint16)(A) & 0x00ff) << 8))#define BigtoLittle32(A) ((((uint32)(A) & 0xff000000) >> 24) | \ (((uint32)(A) & 0x00ff0000) >> 8) | \(((uint32)(A) & 0x0000ff00) << 8) | \(((uint32)(A) & 0x000000ff) << 24))1.4 大端小端检测方法如何检查处理器是big-endian还是little-endian?联合体union的存放顺序是所有成员都从低地址开始存放,利用该特性就可以轻松地获得了CPU对内存采用Little-endian还是Big-endian模式读写:int checkCPUendian(){union{unsigned int a;unsigned char b;} un;c.a = 1;return (c.b == 1);}2. 网络字节顺序2.1 概述> 字节内的比特位不受这种顺序的影响比如一个字节 1000 0000 (或表示为十六进制80H)不管是什么顺序其内存中的表示法都是这样。
大端与小端模式及其举例说明
1. 什么是大端,什么是小端:所谓的大端模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中;所谓的小端模式,是指数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中。
2.为什么会有大小端:为什么会有大小端模式之分呢?这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为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处理器还可以由硬件来选择是大端模式还是小端模式。
3.大小端在内存中的存放方式举例:例如,16bit宽的数0x1234在Little-endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)为:而在Big-endian模式CPU内存中的存放方式则为:而在Big-endian模式CPU内存中的存放方式则为:4.如何测试编译器是大端还是小端:下面这段代码可以用来测试一下你的编译器是大端模式还是小端模式:#include <stdio.h>int main(){short int x;char x0,x1;x=0x1122;x0=((char *)&x)[0]; //低地址单元x1=((char *)&x)[1]; //高地址单元printf("x0=0x%x,x1=0x%x",x0,x1);//若x0=0x11,则是大端; 若x0=0x22,则是小端......return 0;}以下是我在dev C++里面运行的结果,从结果来看,dev C++用的是小端模式;。
关于大小端、位域的一些概念详解
关于⼤⼩端、位域的⼀些概念详解对于像C++中的char这样的数据类型,它本⾝就是占⽤⼀个字节的⼤⼩,不会产⽣什么问题。
但是当数制类型为int,在32bit 的系统中,它需要占⽤4个字节(32bit),这个时候就会产⽣这4个字节在寄存器中的存放顺序的问题。
⽐如int maxHeight = 0x12345678,&maxHeight = 0x0042ffc4。
具体的该怎么存放呢?这个时候就需要理解计算机的⼤⼩端的原理了。
就是把数值的⾼位字节放在内存的低位地址上,把数值的地位字节放在内存的⾼位地址上。
就是把数字的⾼位字节放在⾼位的地址上,低位字节放在低位地址上。
我们常⽤的x86结构都是⼩端模式,⽽⼤部分DSP,ARM也是⼩端模式,不过有些ARM是可以选择⼤⼩端模式。
所以对于上⾯的maxHeight是应该以⼩端模式来存放,具体情况请看下⾯两表。
地址0x0042ffc40x0042ffc50x0042ffc60x0042ffc7数值0x780x560x340x12地址0x0042ffc40x0042ffc50x0042ffc60x0042ffc7数值0x120x340x560x78通过上⾯的表格,可以看出来⼤⼩端的不同,在这⾥⽆法讨论那种⽅式更好,个⼈觉得似乎⼤端模式更符合我的习惯。
(注:在这⾥我还要说⼀句,其实在计算机内存中并不存在所谓的数据类型,⽐如char,int等的。
这个类型在代码中的作⽤就是让编译器知道每次应该从那个地址起始读取多少位的数据,赋值给相应的变量。
)在计算机中是采⽤⼆进制0和1来表⽰数据的,每⼀个0或者1占⽤1位(bit)存储空间,8位组成⼀个字节(byte),为计算机中数据类型的最⼩单位,如char在32bit系统中占⽤⼀个字节。
但是正如我们知道的,有时候程序中的数据可能并不需要这么的字节,⽐如⼀个开关的状态,只有开和关,⽤1和0分别替代就可以表⽰。
此时开关的状态只需要⼀位存储空间就可以满⾜要求。
大小端字节序
大小端字节序大小端字节序是一种数据存储结构,可以让计算机更有效地存储和处理数据。
本文将详细讨论大小端字节序,其原理、用途及其与其他字节序顺序的比较。
大小端字节序是操作多字节数据的一种标准,它指定了字节的存储顺序,以决定数据如何在存储器中组织和传输。
“大端”字节序表示数据中最重要的字节(即最高阶字节)存储在最低的存储单元(即地址低的存储单元)上。
“小端”字节序表示数据中最重要的字节存储在最高的存储单元上(即地址高的存储单元)。
大小端字节序的定义有助于确保数据在操作系统之间或媒介之间传输时保持一致性,这是因为当字节在传输过程中按照特定的字节序(大端或小端)组织时,接收端可以将其重构到正确的格式中。
此外,大小端字节序还有助于确定数据的字节顺序,从而使胝更有效地处理数据。
举个例子,当一个芯片处理器处理多个字节的数据时,最重要的位可能会被写入最低的存储单元(大端)或最高的存储单元(小端)。
这是因为处理器以某种方式读取数据,并期望数据以其特定的字节序组织,以便以最有效的方式处理它们。
而且,大小端字节序可与其他字节序对比,以有效理解它们之间的不同。
有六种类型的字节序,即大端字节序、小端字节序、中间字节序、双字节序、正转序和反转序。
大小端字节序是最常用的,而双字节序是特殊字节序,它在存储特定的双字数据时很有用。
最后,大小端字节序的目的是使计算机更有效地存储和处理数据。
它要求数据在传输过程中保持一致性,并且确定字节的存储顺序,以便计算机达到最佳的处理效率。
此外,它也可以与其他字节序进行对比,以便用户更好地了解它们之间的不同。
总之,大小端字节序是存储多字节数据的标准,在调整计算机以最佳性能处理数据时非常有用。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
深入浅出大端和小端文章一:端模式(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)。
地址偏移大端模式小端模式0x0012(OP0)78(OP3)0x0134(OP1)56(OP2)0x0256(OP2)34(OP1)0x0378(OP3)12(OP0)如果将一个16位的整数0x1234存放到一个短整型变量(short)中。
这个短整型变量在内存中的存储在大小端 模式由下表所示。
地址偏移大端模式小端模式0x0012(OP0)34(OP1)0x0134(OP1)12(OP0)由上表所知,采用大小模式对数据进行存放的主要区别在于在存放的字节顺序,大端方式将高位存放在低地址,小端方式将 高位存放在高地址。
采用大端方式进行数据存放符合人类的正常思维,而采用小端方式进行数据存放利于计算机处理。
到目前为止,采用大端或者小端进行数据存 放,其孰优孰劣也没有定论。
有的处理器系统采用了小端方式进行数据存放,如Intel的奔腾。
有的处理器系统采用了大端方式进行数据存放,如 IBM半导体和Freescale的PowerPC处理器。
不仅对于处理器,一些外设的设计中也存在着使用大端或者小端进行数据存放的选择。
因此在一个处理器系统中,有可能存在大端和小端模式同时存在的现象。
这一现象为系统的软硬件设计带来了不小的麻烦, 这要求系统设计工程师,必须深入理解大端和小端模式的差别。
大端与小端模式的差别体现在一个处理器的寄存器,指令集,系统总线等各个层次中。
1.1.1 从软件的角度理解端模式从软件的角度上,不同端模式的处理器进行数据传递时必须要考虑端模式的不同。
如进行网络数据传递时,必须要考虑端模 式的转换。
有过Socket接口编程经验的程序员一定使用过以下几个函数用于大小端字节序的转换。
¨ #define ntohs(n) //16位数据类型网络字节顺序到主机字节顺序的转换¨ #define htons(n) //16位数据类型主机字节顺序到网络字节顺序的转换¨ #define ntohl(n) //32位数据类型网络字节顺序到主机字节顺序的转换¨ #define htonl(n) //32位数据类型主机字节顺序到网络字节顺序的转换其中互联网使用的网络字节顺序采用大端模式进行编址,而主机字节顺序根据处理器的不同而不同,如PowerPC处理 器使用大端模式,而Pentuim处理器使用小端模式。
大端模式处理器的字节序到网络字节序不需要转换,此时ntohs(n)=n,ntohl = n;而小端模式处理器的字节序到网络字节必须要进行转换,此时ntohs(n) = __swab16(n),ntohl =__swab32(n)。
__swab16与__swab32函数定义如下所示。
#define ___swab16(x){__u16 __x = (x);((__u16)((((__u16)(__x) & (__u16)0x00ffU) << 8) |(((__u16)(__x) & (__u16)0xff00U) >> 8) ));}#define ___swab32(x){__u32 __x = (x);((__u32)((((__u32)(__x) & (__u32)0x000000ffUL) << 24) |(((__u32)(__x) & (__u32)0x0000ff00UL) << 8) |(((__u32)(__x) &(__u32)0x00ff0000UL) >> 8) |(((__u32)(__x) &(__u32)0xff000000UL) >> 24) ));}PowerPC处理器提供了lwbrx,lhbrx,stwbrx,sthbrx四条指令用于处理字节序的转换以优 化__swab16和__swap32这类函数。
此外PowerPC处理器中的rlwimi指令也可以用来实现__swab16和__swap32这类函 数。
在Linux PowerPC中,定义了一系列有关字节序转换的函数,其详细定义在./include/asm-powerpc/byteorder.h文件中。
程序员在对普通文件进行处理也需要考虑端模式问题。
在大端模式的处理器下对文件的32,16位读写操作所得到的结果 与小端模式的处理器不同。
读者单纯从软件的角度理解上远远不能真正理解大小端模式的区别。
事实上,真正的理解大小端模式的区别,必须要从系统的角度,从指 令集,寄存器和数据总线上深入理解,大小端模式的区别。
1.1.2 从系统的角度理解端模式除了4.2.1节中,软件上对不同端模式编程上的差异,处理器在硬件上也由于端模式问题在设计中有所不同。
从系统的 角度上看,端模式问题对软件和硬件的设计带来了不同的影响,当一个处理器系统中大小端模式同时存在时,必须要对这些不同端模式的访问进行特殊的处理。
PowerPC处理器主导网络市场,可以说绝大多数的通信设备都使用PowerPC处理器进行协议处理和其他控制信 息的处理,这也可能也是在网络上的绝大多数协议都采用大端编址方式的原因。
因此在有关网络协议的软件设计中,使用小端方式的处理器需要在软件中处理端模式 的转变。
而Pentium主导个人机市场,因此多数用于个人机的外设都采用小端模式,包括一些在网络设备中使用的PCI总线,Flash等设备,这也要求 硬件工程师在硬件设计中注意端模式的转换。
本书中的小端外设是指这种外设中的寄存器以小端方式进行存储,如PCI设备的配置空间,NOR FLASH中的寄存器等等。
对于有些设备,如DDR颗粒,没有以小端方式存储的寄存器,因此从逻辑上讲并不需要对端模式进行转换。
在设计中,只 需要将双方数据总线进行一一对应的互连,而不需要进行数据总线的转换。
如果从实际应用的角度说,采用小端模式的处理器需要在软件中处理端模式的转换,因为采用小端模式的处理器在与小端外 设互连时,不需要任何转换。
而采用大端模式的处理器需要在硬件设计时处理端模式的转换。
大端模式处理器需要在寄存器,指令集,数据总线及数据总 线与小端外设的连接等等多个方面进行处理,以解决与小端外设连接时的端模式转换问题。
在寄存器和数据总线的位序定义上,基于大小端模式的处理器有所不同。
一个采用大端模式的32位处理器,如基于E500内核的MPC8541,将其寄存器的最高位msb(most significant bit)定义为0,最低位lsb(lease significant bit)定义为31;而小端模式的32位处理器,将其寄存器的最高位定义为31,低位地址定义为0。
与此向对应,采用大端模式的32位处理器数据总线的最高位为0,最高位为31;采用小端模式的32位处理器的数据总 线的最高位为31,最低位为0。
如图4.5所示。
OP0OP1OP2OP3OP0OP1OP2OP33131图4.5大小端模式处理器的寄存器的定义大端模式处理器寄存器位序定义小端模式处理器寄存器位序定义大小端模式处理器外部总线的位序也遵循着同样的规律,根据所采用的数据总线是32位,16位和8位,大小端处理器外 部总线的位序有所不同。
¨ 大端模式下32位数据总线的msb是第0位,MSB是数据总线的第0~7的字段;而lsb是第31位,LSB是第24~31字段。
小端模式下32位总线的 msb是第31位,MSB是数据总线的第31~24位,lsb是第0位,LSB是7~0字段。
¨ 大端模式下16位数据总线的msb是第0位,MSB是数据总线的第0~7的字段;而lsb是第15位,LSB是第8~15字段。
小端模式下16位总线的 msb是第15位,MSB是数据总线的第15~7位,lsb是第0位,LSB是7~0字段。
¨ 大端模式下8位数据总线的msb是第0位,MSB是数据总线的第0~7的字段;而lsb是第7位,LSB是第0~7字段。
小端模式下8位总线的msb是第 7位,MSB是数据总线的第7~0位,lsb是第0位,LSB是7~0字段。
由上分析,我们可以得知对于8位,16位和32位宽度的数据总线,采用大端模式时数据总线的msb和MSB的位置都 不会发生变化,而采用小端模式时数据总线的lsb和LSB位置也不会发生变化。
为此,大端模式的处理器对8位,16位和32位的内存访问(包括外设的访问)一般都包含第0~7字段,即MSB。
小 端模式的处理器对8位,16位和32位的内存访问都包含第7~0位,小端方式的第7~0字段,即LSB。
由于大小端处理器的数据总线其8位,16位和32位宽度的数据总线的定义不同,因此需要分别进行讨论在系统级别上如 何处理端模式转换。
在一个大端处理器系统中,需要处理大端处理器对小端外设的访问。
1.1.2.1 大端处理器对32位小端外设进行访问大端处理器采用32位总线与小端外设进行访问时,大端处理器的32位数据总线的第0~7位用来处理OP0,第 8~15位用来处理OP1,第16~23位用来处理OP2,第24~31位用来处理OP3。
而32位的小端设备使用数据总线的第31~24位用来处理 OP0,第23~16位用来处理OP1,第15~8位用来处理OP2,第7~0位用来处理OP3。
大端处理器,如MPC8541,使用stw,sth,stb和lwz,lhz,lbz指令对32位的外部设备进行访 问。
在这些指令结束后,存放在外部设备的数据将被读入MPC8541的通用寄存器中。
为保证软件的一致性,当访问结束后,存放在通用寄存器的字节序,即 OP0,OP1,OP2和OP3必须要和存放在小端外设的字节序一致。