小端模式和大端模式——踩坑记录

大端小端

1 前言

在做项目时,需要将报文发送给硬件端,报文打包我都是用的大端写入Bytebuf(使用的netty),老大审查代码时,说我写错了,说硬件那边要求是小端传输。不过改成小端写入也容易,重要的是牢记这个知识点。于是趁这个机会复习一下大端和小端。

2 概念

大端(Big-Endian)和小端(Little-Endian)的定义如下:

小端(Little-Endian)数据的低位字节位存放在内存的低地址端,高位字节存放在内存的高地址端。

大端(Big-Endian) 数据的高位字节位存放在内存的低地址端,低位字节存放在内存的高地址端。

2.1 什么是低地址、低地址

地址编号小的是低地址,地址编号大的是高地址

image-20231027003002141.png

2.2 什么是低位字节、高位字节

那16进制的数字0x12345678来说,它有4个字节(一个字节八位,而两个16进制的数字占位,一个字节能表示的最大数字位0xFF)

 低地址   <===============   高地址
高位字节  <===============  低位字节 
 0x12   |  0x34  |  0x56  |  0x78

在大端模式下的内存存储布局为

 低地址   <===============   高地址
高位字节  <===============  低位字节 
 0x12   |  0x34  |  0x56  |  0x78

在小端模式下的内存存储布局为

 低地址   <===============   高地址
高位字节  <===============  低位字节 
 0x78   |  0x56  |  0x34  |  0x12

3. 举例

3.1 代码

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

import static io.netty.buffer.ByteBufUtil.appendPrettyHexDump;
import static io.netty.util.internal.StringUtil.NEWLINE;


public class TestEndian {
    
    public static void main(String[] args) {
        ByteBuf buffer = Unpooled.buffer();
        // 大端写入
        buffer.writeInt(0x12345678);
        log(buffer);

        ByteBuf buffer2 = Unpooled.buffer();
        // 小端写入
        buffer2.writeIntLE(0x12345678);  
        log(buffer2);
    }
    
    /**
     * 显示数据在ByteBuf中的存储接口1
     * @param buffer ByteBuf
     */
    private static void log(ByteBuf buffer){
        int length=buffer.readableBytes();
        int rows=length/16+(length%15==0?0:1)+4;
        StringBuilder buf=new StringBuilder(rows*80*2)
                .append("read index:").append(buffer.readerIndex())
                .append(" write index:").append(buffer.writerIndex())
                .append(" capacity:").append(buffer.capacity())
                .append(NEWLINE);
        appendPrettyHexDump(buf,buffer);
        System.out.println(buf.toString());
    }
}

3.2 控制台结果

read index:0 write index:4 capacity:256
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 12 34 56 78                                     |.4Vx            |
+--------+-------------------------------------------------+----------------+
read index:0 write index:4 capacity:256
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 78 56 34 12                                     |xV4.            |
+--------+-------------------------------------------------+----------------+

控制台中,0,1,2,3,4,...,f,代表从低地址到高地址,第二行可以看到:

  • 大端写入时,高位字节位存放在内存的低地址端低位字节存放在内存的高地址端
  • 小端写入时,低位字节位存放在内存的低地址端高位字节存放在内存的高地址端
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 大端模式和小端模式 Big-Endian和Little-Endian的定义如下: Little-Endian就是低...
    01_小小鱼_01阅读 4,268评论 0 0
  • 一、概述 字节序:字节在电脑中存放时的序列与输入/输出时的序列;也指的是存放多字节数据的字节(byte)的顺序,典...
    神奇的考拉阅读 13,697评论 0 2
  • 一、定义: 大端模式(Big Endian):数据的高字节,保存在内存的低地址中;数据的低字节,保存在内存的高地址...
    突然的自我_39c1阅读 4,097评论 0 1
  • 最近和硬件通讯,需要补习这些知识 Little-Endian就是低位字节排放在内存[https://so.csdn...
    测试_机器猫阅读 903评论 0 0
  • 大端和小端指数据在内存中存储模式,它由CPU决定 大端模式:是指将数据的低位(比如 1234 中的 34 就是低位...
    温岭夹糕阅读 2,515评论 0 0