良许Linux教程网 干货合集 什么是大小端模式?

什么是大小端模式?

一、大小端模式的定义

大端模式(Big-Endian)是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中。

小端模式(Little-Endian)是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中。

二、命名来源

“Big-endian”和”Little-endian”这两个术语来源于乔纳森·斯威夫特的讽刺小说《格列佛游记》。在小说中,小人国内部分为两派,一派要求从鸡蛋的大头砸开,另一派要求从鸡蛋的小头砸开。这个故事被借用来讽刺计算机领域中的数据储存顺序的争议。

三、简单区分方法

以下以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) -- 低位  --------------低地址

内存地址 小端模式存放内容 大端模式存放内容
0x4000 0x78 0x12
0x4001 0x56 0x34
0x4002 0x34 0x56
0x4003 0x12 0x78

四、为什么会有大小端模式之分呢?

这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为 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处理器还可以随时在程序中(在ARM Cortex 系列使用REV、REV16、REVSH指令 )进行大小端的切换。

五、判断处理器是大端模式还是小端模式?

1、因特尔i3-3110M处理器

/********************************************************************************************************* 判断大小端********************************************************************************************************/#include 
// 主函数int main(void){    int a = 0x12345678;    char *cp = (char*)&a;    if (*cp == 0x78)    {        printf("little endian\n");  //运行结果    }    else    {        printf("big endian\n");    }
    return 0;} 

运行结果为: image-20231011220417160

即因特尔i3-3110M处理器为小端存储模式。

2、STM32F407

#include "stm32f4xx.h"
int main(void){     int u = 367328153; // 原始数据15 E4 FB 99    int* k = &u;    return 0;}

编译连接然后下载到开发板上,然后启动调试,通过监视窗口可以看到u的地址,然后在内存窗口可以看到字节序是反序的,所以说明STM32F407是小端的。据某些资料说ARM内核是可以设置大小端的,但是STM32是外设自动进入了小端,似乎是无法调整的。

image-20231011220421284
image-20231011220421284

3、89C52

最后来一个大端的例子。手头上没有51的开发板,所以用的是软件仿真。

#include 
int main(){    int longbit = sizeof(long);
    long u = 367328153; // 原始数据15 E4 FB 99    long* k = &u;
    return 0;}

结果:

image-20231011220425207
image-20231011220425207

六、应用场景

1、不同端模式的处理器进行数据传递时必须要考虑端模式的不同。

2、在网络上传输数据时,由于数据传输的两端对应不同的硬件平台,采用的存储字节顺序可能不一致。所以在TCP/IP协议规定了在网络上必须采用网络字节顺序,也就是大端模式。对于char型数据只占一个字节,无所谓大端和小端。而对于非char类型数据,必须在数据发送到网络上之前将其转换成大端模式。接收网络数据时按符合接受主机的环境接收。

七、现阶段状况

目前Intel的80×86系列芯片是唯一还在坚持使用小端的芯片,ARM芯片默认采用小端,但可以切换为大端;而MIPS等芯片要么采用全部大端的方式储存,要么提供选项支持大端——可以在大小端之间切换。

另外,对于大小端的处理也和编译器的实现有关,在C语言中,默认是小端(但在一些对于单片机的实现中却是基于大端,比如Keil 51C),Java是平台无关的,默认是大端。在网络上传输数据普遍采用的都是大端。

以上就是良许教程网为各位朋友分享的Linu系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你 !

137e00002230ad9f26e78-265x300
本文由 良许Linux教程网 发布,可自由转载、引用,但需署名作者且注明文章出处。如转载至微信公众号,请在文末添加作者公众号二维码。
良许

作者: 良许

良许,世界500强企业Linux开发工程师,公众号【良许Linux】的作者,全网拥有超30W粉丝。个人标签:创业者,CSDN学院讲师,副业达人,流量玩家,摄影爱好者。
上一篇
下一篇

发表评论

联系我们

联系我们

公众号:良许Linux

在线咨询: QQ交谈

邮箱: yychuyu@163.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部