当前位置: 首页 > news >正文

厘清大小端:分清数值轴、地址轴与书写轴

关于字节序的讨论中,“左”“右”“高”“低”等表述常被混用,导致理解困难。解决这一问题的关键在于先将相关概念放回各自的“轴”:数值轴、地址轴与书写轴。分清三条轴之后,大小端的本质就会变得清晰而直观。 

一、三个“轴”的定义 
(一)数值轴(高位与低位,MSB/LSB) 
高位与低位依据权重定义:在同一数据中,权重更大的位或字节称为“高位”(Most Significant),权重更小者称为“低位”(Least Significant)。
对应术语为 MSB(最高有效位)与 LSB(最低有效位),以及 MSByte(最高有效字节)与 LSByte(最低有效字节)。此处讨论的是数值意义,与内存地址无关。

(二)地址轴(低地址与高地址) 
地址是内存中位置的编号。地址数值较小者为低地址,较大者为高地址。它仅描述“数据存放在何处”,不蕴含“高位”“低位”的含义。

(三)书写轴(左与右) 人类书写二进制或十六进制时,习惯将高位写在左侧、低位写在右侧。这只是排版习惯,不能用于定义大小端或高低位。

二、大小端的本质:
数值轴与地址轴的对齐规则

大小端描述的是“数值轴”与“地址轴”的对齐方式。 大端(Big-endian)规定高字节放在低地址,可理解为“大头在前”。 

小端(Little-endian)规定低字节放在低地址,可理解为“小头在前”。 

网络字节序采用大端。 

示例一:以 32 位数值 0x12345678 为例(MSByte 为 0x12,LSByte 为 0x78)。假定起始地址为 A,且地址自左向右递增。 

大端(高字节在低地址): 
A: 0x12 A+1: 0x34 A+2: 0x56 A+3: 0x78 

小端(低字节在低地址): 
A: 0x78 A+1: 0x56 A+2: 0x34 A+3: 0x12 

从视觉上看,大端的内存排列与书写顺序一致;小端的内存排列与书写顺序相反。但需要强调的是,这只是视觉效果,与大小端的定义无关。

三、为何“左/右”容易造成误解
“左/右”属于书写轴,而“低/高地址”属于地址轴。如果在画内存示意图时不先标注地址方向,很容易把纸面上的“左/右”误解为内存的“低/高地址”。

实务建议如下:
先在图上明确标注“地址从左到右递增”,随后再根据大小端规则,将 MSByte 与 LSByte 依次放入对应地址。如此处理,混淆将自然消失。 

四、术语与常见误解的澄清
第一,所谓“高字节等于最右边的字节”属于错误说法。书写时左边是高位、右边是低位;“左右”仅是排版方向。 

第二,正确缩写为 LSB(Least Significant Bit/Byte),而非 LSM。 

第三,“无论大小端都先收发 MSB”并不成立。位的传输顺序(位序)与字节序是彼此独立的约定,需以具体接口或协议为准。
常见情形包括:UART 通常 LSB 先发,I2C 规定 MSB 先发,SPI 可配置为二者之一;以太网在协议字段层面采用网络字节序(大端),但在物理层一个字节内常按 LSB 先发。 

第四,“计算机从低地址开始读取”并不是大小端的定义。
CPU 将若干字节组合为寄存器值的方式由硬件与总线约定决定;大小端仅规定“哪一个字节放在何处”。 

第五,直接传输结构体的二进制表示在跨平台情形下并不可靠。
除了字节序问题,还涉及对齐与填充等实现细节。 

五、字节序与位序是两件事
字节序(endianness)规定多字节数据在内存或报文中各字节与地址的对应关系。 

位序(bit order)规定一个字节内比特的发送或接收顺序。 二者互不蕴含,需分别查阅各自的规范。工程实践中,协议层通常以字节为单位规定字节序,而物理层可能另行规定位序。 

六、进一步的示例 
(一)从数值到内存(十六进制示例见“示例一”) (二)从内存到数值 
已知地址 A…A+3 依次存放 
0x78、0x56、0x34、0x12。 
在小端主机上,这四个字节解释为 0x12345678。
在大端主机上,这四个字节解释为 0x78563412。

(三)以一个不同的二进制数值说明 MSB/LSB 与大小端
考虑 16 位二进制数 0b1100_0110_0011_1010(等于 0xC63A)。 
位层面上,MSB(位)为最左侧的一位 1,LSB(位)为最右侧的一位 0。 
按字节划分,MSByte 为 0xC6,LSByte 为 0x3A。 
若起始地址为 A: 
大端:A: 0xC6 A+1: 0x3A 
小端:A: 0x3A A+1: 0xC6 
以上再次表明,MSB/LSB 的判定源自数值权重,而非内存位置;大小端仅改变多字节在地址上的排列顺序。 

七、在代码中的常用做法 
(一)检测本机字节序(C 语言,使用 unsigned char 指针,符合标准) 
```c
#include <stdio.h> 
#include <stdint.h> 
int main(void)
{
uint16_t x = 0x0102;
const unsigned char *p = (const unsigned char*)&x;
if (p[0] == 0x02)
puts("little-endian");
else
puts("big-endian");
return 0;

``` 
(二)常见转换与库支持
C 语言和 POSIX/WinSock 提供 htons、htonl、ntohs、ntohl 用于与网络字节序(大端)之间转换。
GCC/Clang 提供 __builtin_bswap16/32/64 用于字节翻转。C++20 可使用 <bit> 中的 std::endian 与 byteswap。 
在 Python 中,sys.byteorder 可查看本机字节序;int.to_bytes 与 int.from_bytes 可在指定 byteorder='big' 或 'little' 的前提下进行序列化与反序列化。 

八、为何同时存在两种字节序
大端更贴近人类阅读习惯,输出与比对较为直观,因此许多网络协议与文件格式倾向采用大端以便跨平台一致。
小端在若干底层实现上更为自然,例如逐步扩展整数宽度、进行多字节加法或在部分体系结构上实现高效,因此在通用处理器(如 x86、RISC‑V 以及大多数默认配置的 ARM)中得到广泛采用。
现实格局大致为:处理器世界以小端为主,跨平台协议与部分文件格式偏好大端。 

九、归纳与记忆要点
高位与低位属于数值轴,指的是权重大小;高地址与低地址属于地址轴,指的是存放位置;左与右属于书写轴,指的是排版方向。 

大小端只回答一个问题:最高(或最低)有效字节放在低地址还是高地址。 网络字节序采用大端;位序与字节序彼此独立,应分别查阅规范。 画内存图时宜先标注地址递增方向,再按端序规则放置各字节。 

http://www.dtcms.com/a/400429.html

相关文章:

  • 保定做网站电话北京市住房建设投资中心网站
  • 如何优化唯品会库存API性能?
  • 四川住房和城乡建设部官方网站WordPress文章不置顶
  • 建设图片展示网站网站服务器指的是什么
  • 卖东西的网站怎么建设app开发需要哪些软件
  • 分析可口可乐网站建设的目的男女做爰视频网站在线
  • 网站模板平台资源电子商务网站功能模块
  • 外贸网站响应式伊春住房和城乡建设局网站
  • 网站制作费用需要多少钱网站主机服务器
  • 河南工会考试真题分享
  • 有需要做网站的吗网站建设设置分享功能
  • 社交网站开发项目计划报告最好最值得做的调查网站
  • 处理视频抽帧并转换成json
  • 东大桥做网站的公司中国建设银行 网站登录
  • 成都科技网站建设联免费书画网站怎么做的
  • [SQL] 给定起止日期,计算出日期行
  • 育苗盘补苗路径规划研究_2.5
  • 建设网站的网站叫什么男网站案例展示分类
  • 什么是网络营销广东宣布即时优化调整
  • 杭州国外网站推广公司企业微信app下载安装不了
  • java-Collection集合-Set集合
  • 明亮的夜晚
  • 内江建网站广州公司注册需要哪些资料
  • 仙居网站建设网络搭建是什么工作
  • 设计网站公司咨询亿企邦影视文化网站建设
  • 苏州网站推广搭建小程序要钱吗
  • 石家庄网站开发与优化html网页制作房地产页面
  • 网站怎么做二维码链接地址建筑网站建设需要注意哪些
  • 如何把怎己做的网页放到网站上开放平台模式
  • 建设项目网站wordpress还有价值么