Skip to content

定义Definition

字节序与多字节值

Byte order · Endianness · Little endian · Big endian

把内存地址顺序与字节的数值权重分开,按指定端序组装整数并定位跨格式误读。

形式陈述 ​

内存按字节寻址,M[a] 是地址 a 处的八位值。取非负整数地址 a 和正整数 n,且访问不环绕地址空间。读取从 a 开始的 n 字节无符号整数时,小端与大端分别定义为

LEn(a)=∑i=0n−1M[a+i]28i,BEn(a)=∑i=0n−1M[a+i]28(n−1−i).

存储操作是相反的拆分:小端把数的最低有效字节放在最低地址,大端把最高有效字节放在那里。字节内部的 bit 权重仍按定宽表示解释;端序不是把每个字节中的 bit 反转。

如果读的是补码整数,先按端序组成 8n 位串,再作有符号解释。字节序与有无符号是两个独立选择。

直觉

地址顺序回答“先读哪个格子”,数值权重回答“这个格子值多少个 256i”。端序只约定两者如何对应。寄存器中的 0x12345678 是一个数值写法;只有把它拆到连续地址,才会出现大端或小端的问题。

一个字节的读取在两种公式下完全相同,因为 n=1 时只有权重一。能跨端序逐字节搬运,并不意味着随后用本机整数 load 解释它也相同。

例子与边界

同一字节序列的两种答案 ​

设地址 0x100 到 0x103 依次保存 78 56 34 12。四字节小端读值得 0x12345678;大端读值得 0x78563412。两者访问的是相同四个地址,差别只在加权方式。

从 0x101 开始读取两个字节,小端得 0x3456,大端得 0x5634。这说明端序定义也适用于字段内部的子读取,不必假定每次都从四字节边界开始。该读取在特定机器上能否执行,另由访存对齐规则决定。

文件头不是本机整数数组 ​

一个外部格式规定长度字段为两字节大端,实际字节为 01 00,因此长度为 256。小端机器若直接把它当本机十六位整数读,会得到 1。正确解析可逐字节计算 256b0+b1,无需改变文件的其余字节。

文本 "AB" 的两个编码字节按地址次序保存和输出时,无须颠倒。把每两个文本字节都“换端”会变成 "BA",因为文本序列不是一个隐含的大端整数数组。结构体中的不同宽度字段也必须逐字段解释,不能反转整个结构体。

字节交换不能代替格式说明 ​

若字段值恰为 00 00 或 AB AB,交换字节不改变结果,这类测试会掩盖错误。测试应选择各字节不同的值,并明确字段宽度;对两字节正确的交换,不保证四字节字段也正确。

推论与应用

指令集状态机中,load/store 的含义需要把字节数组与寄存器位串连接起来。本单元的教学机器明确选择小端,避免把执行环境未说明的细节藏进 M[a] 这种符号。

端序不保证原子性,也不规定一次访存跨几个缓存块。前者是可观察并发行为的契约,后者要知道地址、宽度和块大小。把三个问题分开,才能解释“字节值都正确,但多字节读取得到撕裂值”等现象。

参考资料
关系图谱18 个相邻概念 · 1 类关系

拖动节点调整位置。

显示关系

显示:依赖

  1. 前置三跳
  2. 前置二跳
  3. 前置一跳
  4. 当前条目
  5. 后续一跳
  6. 后续二跳
  7. 后续三跳
文字版关系按与当前条目的最短距离分组