3.5.3 什么是“大端”和“小端”

对于什么是“大端”和“小端”?《UNIX网络编程•卷一》中关于这个概念做了简单的概括。不仅限于这本书,很多计算机书籍都是这样介绍这个概念的,你也会在和计算机相关的不同领域的书中遇到它们。尽管很令人疑惑,但是在继续深入理解Modbus协议之前,最好对这两个术语的概念有所理解。

所谓的大端模式,是指数据的低位保存在内存的高地址中,数据的高位保存在内存的低地址中。

所谓的小端模式,是指数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中。

用图形加深理解,如图3-4所示。

图3-4 字节序和大小端

在图3-4中,顶部标明内存地址增长方向从右到左,在底部标明内存地址增长的方向为从左到右。并且还标明最高有效位(即most significant bit, MSB)是这个16位值最左边一位,最低有效位(即least significant bit, LSB)是这个16位值最右边一位。可见,术语“小端”和“大端”表示多个字节值的哪一端(小端或大端)存储在该值的起始地址。

例如,16位宽的整数0x1234在Little-Endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)为:

而在Big-Endian模式CPU内存中的存放方式则为:

不止16位的值存在大小端的问题,任意多字节的值都存在排序问题。

例如,32位宽的数(整数或者实数皆可)0x12345678在Little-Endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)为:

而在Big-Endian模式CPU内存中的存放方式则为:

对于大小端这两种字节序目前没有标准可循,都有系统在使用。

实际上,Modbus协议中规定一个寄存器占用16位即2个字节长度,因此,开发之前有必要搞清楚系统的大小端模式和字节序。

对于32位的整数或者实数来说,存在以下4种不同的字节序(ABCD代表各字节):

• Long(float)AB CD

• Long(float)CD AB

• Long(float)BA DC

• Long(float)DC BA

例如:若系统采用字节序为AB CD,则十进制整数123456789(其十六进制为07 5B CD 15)在Modbus消息中发送顺序为07 5B CD 15;而十进制实数123456.00(其十六进制为47 F1 20 00),在Modbus消息中发送顺序为47 F1 20 00。

而对于64位的双精度实数来说,也存在以下4种不同的字节序:

• Double AB CD EF GH

• Double GH EF CD AB

• Double BA DC FE HG

• Double HG FE DC BA

例如:若采用字节序AB CD EF GH,则双精度实数123456789.00(其十六进制为41 9D 6F 34 54 00 00 00)在Modbus消息中发送顺序为41 9D 6F 34 54 00 00 00。