“TCP字节流没有应用消息边界。本页固定一个小格式:每帧先放两字节无符号大端长度 $L=256b 0+b 1$,然后恰好 $L$ 个载荷字节;允许 $L=0$,最大合法长度 $L {\max}…”
形式陈述
内存按字节寻址,
存储操作是相反的拆分:小端把数的最低有效字节放在最低地址,大端把最高有效字节放在那里。字节内部的 bit 权重仍按定宽表示解释;端序不是把每个字节中的 bit 反转。
如果读的是补码整数,先按端序组成
直觉
地址顺序回答“先读哪个格子”,数值权重回答“这个格子值多少个 0x12345678 是一个数值写法;只有把它拆到连续地址,才会出现大端或小端的问题。
一个字节的读取在两种公式下完全相同,因为
例子与边界
同一字节序列的两种答案
设地址 78 56 34 12。四字节小端读值得 0x12345678;大端读值得 0x78563412。两者访问的是相同四个地址,差别只在加权方式。
从 0x3456,大端得 0x5634。这说明端序定义也适用于字段内部的子读取,不必假定每次都从四字节边界开始。该读取在特定机器上能否执行,另由访存对齐规则决定。
文件头不是本机整数数组
一个外部格式规定长度字段为两字节大端,实际字节为 01 00,因此长度为
文本 "AB" 的两个编码字节按地址次序保存和输出时,无须颠倒。把每两个文本字节都“换端”会变成 "BA",因为文本序列不是一个隐含的大端整数数组。结构体中的不同宽度字段也必须逐字段解释,不能反转整个结构体。
字节交换不能代替格式说明
若字段值恰为 00 00 或 AB AB,交换字节不改变结果,这类测试会掩盖错误。测试应选择各字节不同的值,并明确字段宽度;对两字节正确的交换,不保证四字节字段也正确。
推论与应用
指令集状态机中,load/store 的含义需要把字节数组与寄存器位串连接起来。本单元的教学机器明确选择小端,避免把执行环境未说明的细节藏进 M[a] 这种符号。
端序不保证原子性,也不规定一次访存跨几个缓存块。前者是可观察并发行为的契约,后者要知道地址、宽度和块大小。把三个问题分开,才能解释“字节值都正确,但多字节读取得到撕裂值”等现象。
参考资料
- UC Berkeley CS61C,Words, Endianness,课程笔记,访问于 2026-10-08。
- Danny Cohen, “On Holy Wars and a Plea for Peace”, IEN 137, 1980;字节顺序约定的历史讨论。本文以显式地址公式固定所用定义。