目录
[小端序存储(x86/x64 默认):](#小端序存储(x86/x64 默认):)
[四、为什么 x86/x64 使用小端序?](#四、为什么 x86/x64 使用小端序?)

一、概念
字节序(Endianness) 是指多字节数据在内存中的存储顺序。
-
大端序(Big-Endian) :高位字节 存放在低地址(高字节在前)符合人类阅读习惯(从左到右,高位→低位)。
-
小端序(Little-Endian) :低位字节 存放在低地址(低字节在前)与人类阅读习惯相反,但对硬件计算更高效。
x86/x64 架构(Intel/AMD)固定使用小端序,这是硬件层面的强制规则,无法通过软件修改。
二、实际存储对比示例
以数值 0x12345678(DWORD,32位)为例:
0001 0010 0011 0100 0101 0110 0111 1000
小端序存储(x86/x64 默认):
|--------|------|-------------|
| 内存地址 | 存储内容 | 含义 |
| 0x1000 | 0x78 | 最低有效字节(LSB) |
| 0x1001 | 0x56 | 次低字节 |
| 0x1002 | 0x34 | 次高字节 |
| 0x1003 | 0x12 | 最高有效字节(MSB) |
大端序存储:
|--------|------|-------------|
| 内存地址 | 存储内容 | 含义 |
| 0x1000 | 0x12 | 最高有效字节(MSB) |
| 0x1001 | 0x34 | 次高字节 |
| 0x1002 | 0x56 | 次低字节 |
| 0x1003 | 0x78 | 最低有效字节(LSB) |
核心区别:
-
小端序:内存地址从低到高 → 数值从低位到高位。
-
大端序:内存地址从低到高 → 数值从高位到低位。
三、汇编语言中的体现
.data
dwVar dd 0x12345678 ; 定义双字 0x12345678
.code
mov eax, dwVar ; eax = 0x12345678(数值正常)
mov al, byte ptr [dwVar] ; AL = 0x78 (最低字节)
mov ah, byte ptr [dwVar+1] ; AH = 0x56 (次低字节)
在 x86/x64 汇编调试器中查看内存时,你会看到实际存储顺序为:78 56 34 12,这就是小端序的表现。
四、为什么 x86/x64 使用小端序?
-
运算效率:CPU 执行加法、乘法等操作时从最低有效位开始计算,小端序让低位字节放在低地址,减少地址偏移计算。
-
类型转换方便 :将
int转为short时,直接读取低地址即可得到低位部分。 -
历史兼容性:从 8086 开始就采用小端序,后续 x86-64 完全继承以保证二进制兼容。
五、网络与协议中的字节序
-
网络字节序 统一使用大端序(TCP/IP 协议规定)。
-
原因:不同架构的设备通信时必须有统一标准。
常用转换函数(C/C++):
-
htonl()/htons():主机序 → 网络序(小端转大端) -
ntohl()/ntohs():网络序 → 主机序(大端转小端)
六、在逆向工程、汇编开发中的实际应用
在逆向工程(Reverse Engineering)和汇编开发中,字节序是极其重要的知识点:
-
内存数据解析
- 使用调试器(x64dbg、OllyDbg、GDB)查看内存时,必须知道当前是小端序,否则会把
78 56 34 12错误解读为0x78563412。
- 使用调试器(x64dbg、OllyDbg、GDB)查看内存时,必须知道当前是小端序,否则会把
-
结构体重构(Reversing 数据结构)
- 逆向游戏、软件协议时,需要正确识别结构体中多字节字段(如 int、float、指针)的实际内存布局。
-
文件格式解析
- PNG、JPEG、PE/ELF 文件头有固定字节序(部分大端),逆向时需正确转换才能解析文件头信息。
-
网络协议逆向
- 逆向游戏封包、私有协议时,收到的数据通常是大端序,需手动转换为小端序才能得到正确数值。
-
Shellcode / exploit 开发
- 构造payload时,必须严格按照目标程序的字节序填充地址和数值,否则会导致跳转失败或崩溃。
-
跨平台数据处理
- 编写汇编/C++程序与嵌入式设备(部分大端序)通信时,必须进行字节序转换。
实际案例:
逆向一个网络游戏封包,发现其中一个 DWORD 字段在内存中为 78 56 34 12,你应该知道其真实值为 0x12345678(小端序),而不是直接当成 0x78563412。
七、总结
-
x86/x64 :永久小端序(硬件强制)。
-
网络协议 / 部分文件格式 :大端序(人为约定)。
-
核心原则:
-
本地内存操作(汇编/C++) → 按小端序处理,无需转换。
-
网络通信、跨平台、文件解析 → 必须显式转换字节序。
-
掌握字节序,能帮助你在逆向分析中快速、准确地还原程序数据结构和协议逻辑,避免因字节顺序错误导致的分析偏差。这是汇编、逆向工程和底层开发中不可或缺的基础知识。