Endianness 的问题实质就是关于计算机如何存储大的数值的问题。
我们知道一个基本存储单元可以保存一个字节,每个存储单元对应一个地址。对于大于十进制255(16进制0xff)的整数,需要多个存储单元。例如,4660对应于0x1234,需要两个字节。不同的计算机系统使用不同的方法保存这两个字节。在我们常用的PC机中,低位的字节0x34保存在低地址的存储单元,高位的字节0x12保存在高地址的存储单元;而在Sun工作站中,情况恰恰相反,0x34位于高地址的存储单元,0x12位于低地址的存储单元。前一种就被称为Little Endian,后一种就是Big Endian。
如何记住这两种存储模式?其实很简单。首先记住我们所说的存储单元的地址总是由低到高排列。对于多字节的数值,如果先见到的是低位的字节,则系统就是Little Endian的,Little 就是"小,少"的意思,也就对应"低"。相反就是Big Endian,这里 Big "大"对应"高"。
为了加深对Endianness的理解,让我们来看下面的C程序例子:
char a = 1;
char b = 2;
地址偏移量 内存映像
short c = 255; /* 0x00ff */ 0x0000: 01 02 FF 00
long d = 0x44332211; 0x0004: 11 22 33 44
在右侧我们可以见到在基于Intel 80x86的系统上的内存映像,显然我们可以马上判定这一系统是Little Endian的。对于16位的整形数(short)c,我们先见到其低位的0xff,下一个才是0x00。同样对于32位长整形数(long)d,在最低的地址0x0004存的是最低位字节0x11。如果是在Big Endian的计算机中,则地址偏移量从0x0000到0x0007的整个内存映像将为:01 02 00 FF 44 33 22 11。
所有计算机处理器都必须在这两种Endian间作出选择。但某些处理器(如MIPS和IA-64)支持两种模式,可由编程者通过软件或硬件设置一种Endian。以下是一个处理器类型与对应的Endian的简表:
纯Big Endian: Sun SPARC, Motorola 68000,Java Virtual Machine Bi-Endian, 运行Big Endian模式: MIPS运行IRIX, PA-RISC,大多数Power和PowerPC系统 Bi-Endian, 运行Little Endian模式: MIPS 运行Ultrix,大多数DEC Alpha, IA-64运行Linux Little Endian: Intel x86,AMD64,DEC VAX如何在程序中检测本系统的Endianess?可调用下面的函数来快速验证,如果返回值为1,则为Little Endian;为0则是Big Endian:
int testendian() {
int x = 1;
return *((char *)&x);
}
Endianness对于网络通信也很重要。试想当Little Endian系统与Big Endian的系统通信时,如果不做适当处理,接收方与发送方对数据的解释将完全不一样。比如对以上C程序段中的变量d,Little Endian发送方发出11 22 33 44四个字节,Big Endian接收方将其转换为数值0x11223344。这与原始的数值大相径庭。为了解决这个问题,TCP/IP协议规定了专门的"网络字节次序",即无论计算机系统支持何种Endian,在传输数据时,总是数值最高位的字节最先发送。从定义可以看出,网络字节次序其实是对应Big Endian的。
为了避免因为Endianness造成的通信问题,及便于软件开发者编写易于平台移植的程序,特别定义了一些C语言预处理的宏来实现网络字节与主机字节次序之间的相互转换。htons()和htonl()用来将主机字节次序转成网络字节次序,前者应用于16位无符号数,后者应用于32位无符号数。ntohs()和ntohl()实现反方向的转换。这四个宏的原型定义可参考如下(Linux系统中可在netinet/in.h文件里找到):
#if defined(BIG_ENDIAN) && !defined(LITTLE_ENDIAN)
#define htons(A) (A)
#define htonl(A) (A)
#define ntohs(A) (A)
#define ntohl(A) (A)
#elif defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
#define htons(A) ((((uint16)(A) & 0xff00) >> 8) | \
(((uint16)(A) & 0x00ff) << 8))
#define htonl(A) ((((uint32)(A) & 0xff000000) >> 24) | \
(((uint32)(A) & 0x00ff0000) >> 8) | \
(((uint32)(A) & 0x0000ff00) << 8) | \
(((uint32)(A) & 0x000000ff) << 24))
#define ntohs htons
#define ntohl htohl
#else
#error "Either BIG_ENDIAN or LITTLE_ENDIAN must be #defined, but not both."
#endif
分享到:
相关推荐
最后跑代码可能出现错误,将文件endianness.h保存C:\Program Files\tesseract\include\leptonica 完整流程可以参考https://editor.csdn.net/md/?articleId=90347165,现在才知道到达100积分后,后面积分都被CSDN私...
快速CDR eProsima Fast CDR是一个C ++库,提供两种序列化机制。 一种是标准CDR序列化机制,另一种是修改标准的更快实现。 建造 eProsima Fast CDR提供脚本来构建和安装它。 同样在您可以找到使用自动工具Linux...
### 关于ARM处理器的端序性(Endianness)深入解析 #### 概述与定义 在计算机科学领域,端序性(Endianness)是一个关键概念,它指的是多字节数据类型(如整数、浮点数或字符序列)在计算机内存中存储时字节的排列...
在IT领域,Endianness是计算机系统中处理数据的一种方式,它涉及到如何在内存或网络传输中存储和解析数据的顺序。"Endianness-Well"可能是某个项目或库的名称,专注于解决多线程环境下关于字节序的问题。本文将深入...
**2.1 字节序(Endianness)** - **定义**:指多字节数据在内存中的存储顺序。 - **Spice Protocol**:规定使用小端序(little-endian)格式存储多字节数据。 **2.2 数据类型(Datatypes)** - **基本类型**:如...
在计算机科学中,"endianness"是指数据存储的顺序,特别是在多字节数据类型(如整数或浮点数)中。"大端"(Big-endian)和"小端"(Little-endian)是两种主要的字节序类型。大端模式下,数据的最高有效字节存储在...
#### 七、Endianness模式 - **Big Endian**: 最重要的字节存储在最低地址中。 - **Little Endian**: 最重要的字节存储在最高地址中。 例如,对于0x12345678: - **Big-Endian**: 0x00: 0x12 | 0x01: 0x34 | 0x02: ...
### ATA8/ATAPI ACS详解 #### 一、概述 ATA8/ATAPI ACS(AT Attachment 8 - ATA/ATAPI Command Set)是一项重要的技术标准,由美国国家标准委员会(Accredited Standards Committee INCITS)下属的技术委员会T13...
- 在`Options for Target`对话框中,选择`C/C++ Compiler`->`Optimization`选项卡,确保`Endianness`设置正确。 - `Big Endian`: 计算机认为读取的第一个字节是最大的字节。 - `Little Endian`: 计算机认为读取的...
字节序(Endianness):大端和小端 二、应用 结构体是一种数据的归类方式,相比数组或变量更具有整体全面性,例如一个数组只可以放一些按照元素顺序存放的单元变量,即 buffer = {x, x, x, x, x…},i 有多大,数组...
### 大端与小端表示法详解 #### 一、引言 在计算机科学领域,数据的存储方式是一项基础而重要的技术。对于大于255(即超过一个字节)的整数,需要多个字节来进行存储。这些字节如何在内存中排列,涉及到两种主要的...
在计算机科学中,"endianness"是一个重要的概念,主要涉及到数据在内存或网络传输中如何存储和解析的问题。"大端"(Big-Endian)和"小端"(Little-Endian)是两种主要的字节序类型,它们决定了多字节数据(如整数或...
概述 这个 Rust crate 实现了一组用于构建复杂二进制流的类型,主要用于编写对摄取二进制数据的事物的测试。... // `Section`s can be created with either default endianness. let s = Section :: with_endian
- ARM存储类型包括B和D,即little-endianness和big-endianness。 8. **ARMV8处理器特点**: - ARMV8处理器支持巨大的页(hugepage),是64位处理器,支持虚拟化,并且支持secure mode。 9. **二分查找**: - 在...
- 网络设备和原理:比如芯片的字节存储顺序(endianness)。 4. **逻辑推理和智力题**: - 逻辑门电路:通过与门、或门判断输出结果。 - 无限循环识别:通过for循环的条件判断分析。 5. **软件工程和面试流程**...
- **位格式Endianness**:指明数据的字节顺序。 **3.11 总线仲裁机制(重点)** - **信号描述**:用于控制和管理主设备访问总线的信号。 - **总线访问请求**:主设备向仲裁器发送请求以获得总线使用权。 - **总线...
- **Endianness**:指数据存储的方式。ARM支持两种格式:Big Endian(高位字节存储在低地址)和Little Endian(低位字节存储在低地址)。 - **Condition Code (cond)**:用于控制指令执行的条件码。例如,EQ表示相等...
4. 判断计算机字节存储顺序(endianness): - 可以定义一个包含一个大整数(例如,`0x12345678`)的结构体,然后查看这个整数在内存中的字节顺序。如果低字节在前,则是小端(little endian),反之则是大端(big ...
在计算机科学中,"大小端"(Endianness)是指数据在内存或网络传输中存储的顺序。简单来说,就是指多字节数据(如整数或浮点数)是按照高字节优先(Big-Endian)还是低字节优先(Little-Endian)的方式存储的。这个...
// 可以根据需求选择endianness out (file.size()); // 预先发送文件大小 char buffer[1024]; while (!file.atEnd()) { out.write(buffer, file.read(buffer, sizeof(buffer))); } file.close(); ``` 在客户端,...