大端(高位在低地址)--小端(低位在低地址)

本文详细介绍了计算机中的大端和小端存储机制,包括基本概念、数组存储方式、转换方法及检测手段,并通过实例展示了不同字节序下数据的存储区别。
一、概念及详解

  在各种体系的计算机中通常采用的字节存储机制主要有两种: big-endian和little-endian,即大端模式和小端模式。

  先回顾两个关键词,MSB和LSB:

  MSB:MoST Significant Bit ------- 最高有效位
        LSB:Least Significant Bit ------- 最低有效位

  大端模式(big-edian)

  big-endian: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----------------------------------LSB
        val | 1 0 0 0 1 0 1 1 | 1 0 0 0 1 0 1 0 |
        +--------------------------------------------+
        = 0x8 B 8 A

  小端模式(little-endian)

  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-----------------------------------LSB
        val | 1 0 0 0 1 0 1 1 | 1 0 0 0 1 0 1 0 |
        +---------------------------------------------+
        = 0x8 B 8 A

  二、数组在大端小端情况下的存储:

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

  三、大端小端转换方法:

  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?

  联合体uniON的存放顺序是所有成员都从低地址开始存放,利用该特性就可以轻松地获得了CPU内存采用Little-endian还是Big-endian模式读写。

int checkCPUendian()
        {
                union
                {
                        unsigned int a;
                        unsigned char b;
                }c;
                c.a = 1;
                return (c.b == 1);
        }
        /*return 1 : little-endian, return 0:big-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处理器。不仅对于处理器,一些外设的设计中也存在着使用大端或者小端进行数据存放的选择。

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

【用函数判断系统是Big Endian还是Little Endian】

//如果字节序为big-endian,返回true;
//反之为   little-endian,返回false

bool IsBig_Endian()
{
    unsigned short test = 0x1234;
    if(*( (unsigned char*) &test ) == 0x12)
       return TRUE;
   else
       return FALSE;

}//IsBig_Endian()


 

是的,**大端序(Big-Endian)就是“高位字节存储在地址”**,这句话虽然听起来绕,但它是正确的。 --- ### ✅ 正确定义: | 名称 | 含义 | |------------|------| | **大端序(Big-Endian)** | 数据的 **高位字节(Most Significant Byte, MSB)** 存储在 **内存地址处** | | **小端序(Little-Endian)** | 数据的 **低位字节(Least Significant Byte, LSB)** 存储在 **内存地址处** | --- ## 🧠 举个例子说明 假设我们有一个 32 位整数(4 字节): ```c uint32_t value = 0x12345678; ``` 这个数的四个字节分别是: - 高位低位:`12` `34` `56` `78` - 其中 `0x12` 是最高位字节(MSB),`0x78` 是最低位字节(LSB) 把它存入内存地址从 `0x1000` 开始的位置。 ### 🔹 大端序(Big-Endian)存储方式: | 地址 | 内容 | |----------|----------| | 0x1000 | 0x12 ← 高位字节放在地址 | 0x1001 | 0x34 | 0x1002 | 0x56 | 0x1003 | 0x78 ← 低位字节放在高地址 ✅ 符合“**高位地址**”,这就是大端序。 > 📌 记忆法:就像我们写数字一样,`12345678` 是从左到右按高排列 —— 大端序也这样存。 --- ### 🔹 小端序(Little-Endian)存储方式(如 x86/x64 架构): | 地址 | 内容 | |----------|----------| | 0x1000 | 0x78 ← 低位字节放在地址 | 0x1001 | 0x56 | 0x1002 | 0x34 | 0x1003 | 0x12 ← 高位字节放在高地址 ❌ 不符合人类直觉,但现代大多数 CPU(Intel/AMD)都用这种方式。 --- ## 🔍 实际代码验证 ```c #include <stdio.h> int main() { uint32_t value = 0x12345678; unsigned char *ptr = (unsigned char*)&value; printf("Address layout:\n"); for (int i = 0; i < 4; i++) { printf("Addr[%p] = 0x%02x\n", (void*)(ptr + i), ptr[i]); } if (ptr[0] == 0x12) { printf("→ Big-Endian\n"); } else if (ptr[0] == 0x78) { printf("→ Little-Endian\n"); } return 0; } ``` 输出示例(x86_64 上): ``` Addr[0x7fff...00] = 0x78 Addr[0x7fff...01] = 0x56 Addr[0x7fff...02] = 0x34 Addr[0x7fff...03] = 0x12 → Little-Endian ``` --- ## 🌐 常见系统的字节序 | 系统/架构 | 字节序 | 应用场景 | |------------------|---------------|--------| | x86, x86_64 | Little-Endian | PC、服务器 | | ARM | 可配置,通常小端 | 移动设备、嵌入式 | | MIPS | 支持双端 | 路由器等 | | Network Protocol | **Big-Endian** | 所有网络传输标准(又称“网络字节序”) | > ⚠️ 所以在网络编程中,必须使用 `htonl()` / `htons()` 等函数统一为大端序! --- ## ✅ 总结一句话: > **大端序 = 高位字节 → 地址低位字节 → 高地址** > 就像数字书写顺序一样自然,因此也被用作“网络字节序”。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值