计算机系统中的大端模式和小端模式

计算机系统,大端,模式 · 浏览次数 : 705

小编点评

**大小端字节序** 指的是计算机系统中不同平台的数据字节序规则。 **应用场景:** * **跨平台数据交换** * **文件格式** * **数据库存储** * **外部设备通信** * **二进制数据处理** **字节序转换:** 在不同平台上,数据字节序可能不同,因此需要进行字节序转换才能正确处理数据。例如: * **网络协议** 使用 **大端字节序** * **数据库** 使用 **小端字节序** * **外部设备** 可能使用不同的字节序 **注意事项:** * 在进行字节序转换时,需要考虑数据的类型和格式。 * 不同平台上数据的字节序可能不同,因此需要根据具体情况进行处理。

正文

  最近工作中有用到一个知识点,就是大小端,当然这是一个小的知识点,为什么写一个博文呢,我其实是想测试一下chatGPT,所以我开始将自己的想法告诉这个chatbot,让他给我一些写博文的建议,并且给我解答了一些疑惑,今天将自己的学习笔记整理出来展示给大家(by the way,一个有用的搜索引擎和chatbot对我们的工作有着事半功倍的作用,并且它的思路很明显比我更好,如果只是单纯的用在学习上,我觉得这个简直是百科全书)。

  废话不多说了,正文开始。

1,什么是大小端?

  在计算机中,字节序指的是在存储器中,多字节数据的字节存放顺序。大小端是计算机体系结构中的一个概念,用于表示在多字节数据类型中,字节的顺序。在不同的计算机体系结构中,字节顺序可能不同。一些处理器将最高位字节存储在地址最低的位置,这被称为“大端字节序”(高位字节排放在内存的低地址端,低位字节排放在内存的高地址端),而另一些处理器将最低位字节存储在地址最低的位置,这被称为“小端字节序”(低位字节排放在内存的低地址端,高位字节排放在内存的高地址端)。

  例如,假设我们要存储十六进制数0x12345678(十进制数为305419896),在大端字节序下,它的存储顺序为:

12 34 56 78

  而在小端字节下,则为:

78 56 34 12

   以上从左到右=》 低地址(高位)到高地址(低位)。偷个图:

 

2,大小端的历史原因和发展

2.1 为什么会有大小端之分?

  大端和小端的概念最初由IBM的工程师Danny Cohen提出。这两种字节序最初是由不同的计算机厂商开发出来的。早期的计算机在内部存储器和CPU之间使用通信线,用于发送和接收数据。这些通信线被设计为双向的,可以在读和写时使用。因此,数据的字节顺序是很重要的。在当时的计算机中,大端字节序被广泛采用。

  这是由计算机体系结构的设计决定的。在早期的计算机设计中,内存是以字(word)为单位进行读写的,字的长度不同,如16位、32位或64位等。在读写数据时,需要确定数据的字节顺序,以便正确地处理数据。在计算机系统中,以字节为单位,所以每个地址单元都对应一个字节,一个字节为8bit。但是在C语言中除了8bit的char外,还有16bit的short,32bit的long。另外对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器大于一个字节,那么必然存在一个如何将多个字节安排的问题。因此就导致了大端存储和小端存储模式。

  在大端字节序中,最高有效位在最低的地址上,符合人类的习惯,容易理解和记忆。而在小端字节序中,最低有效位在最低的地址上,这种方式更容易实现,因为它可以让计算机在处理字节序列时不需要额外的转换操作,只需要按照顺序依次读写即可。

  实际上,不同的处理器架构和操作系统都有不同的字节序规则,例如x86架构的处理器使用小端字节序,而PowerPC架构的处理器使用大端字节序。因此,在进行数据传输或数据交换时,需要考虑数据的字节序,以确保数据的正确传输和解析。

2.2 大小端的发展历史

  大小端(Endian)是指计算机中字节的排列顺序。它分为大端(Big-endian)和小端(Little-endian)。大端表示高位字节存储在低地址,而小端表示低位字节存储在低地址。大小端的发展历史可以追溯到计算机的早期发展阶段。

  1960s:大小端的概念最早可以追溯到20世纪60年代,IBM的System/360系列计算机采用了大端字节序。这种字节序的设计与人类阅读数字的方式相似,即从高位到低位。

  1970s:在20世纪70年代,DEC公司推出了PDP-11系列计算机,采用了小端字节序。小端字节序的优势在于,对于多字节整数的部分访问和计算更加方便,因为低位字节总是存储在最低的地址。

  1980s:随着计算机技术的发展,许多不同的处理器架构开始出现。例如,Motorola 68000系列处理器采用大端字节序,而Intel x86系列处理器采用小端字节序。这导致了计算机领域内的大小端之争。

  1990s:在20世纪90年代,随着网络技术的普及,计算机之间的数据交换变得越来越重要。因此,网络字节序(Network Byte Order)的概念应运而生。网络字节序采用大端字节序,以确保不同处理器架构之间的数据交换能够顺利进行。

  2000s至今:在21世纪,计算机技术继续发展,处理器架构也趋于多样化。许多处理器,如ARM和PowerPC,支持大小端可配置,使得系统设计者可以根据实际需求选择合适的字节序。此外,一些编程语言和库也提供了跨平台的字节序转换功能,以便在不同字节序的系统之间进行数据交换。

  在早期的计算机体系结构中,大端字节序是主流的存储方式。但是,后来随着英特尔处理器的流行,小端字节序逐渐成为主流。英特尔处理器采用小端字节序的主要原因是,其实现简单且效率高。同时,小端字节序的处理方式也更符合人的直观感觉,因为我们通常是从低位到高位依次读取数据。总之,大小端的发展历史反映了计算机技术的演进和处理器架构的多样化。如今,大小端问题已经不再是一个严重的障碍,因为现代处理器和软件都提供了灵活的解决方案来应对字节序差异。

  

3,大小端的实现原理和存储方式

  在计算机中,大端(Big-Endian)和小端(Little-Endian)是两种不同的数据存储方式。下面我们详细学习一下大小端的实现原理和存储方式,具体定义如下:

  大端字节序(Big-Endian):在大端字节序中,数据的高位字节存储在低位地址上,而数据的低位字节存储在高位地址上。这种方式类似于我们人类习惯的顺序,从左到右,高位到低位。

  存储方式:假设我们有一个32位整数0x12345678,其内存地址为0x1000。在大端字节序的系统中,该整数的存储方式如下:

地址            数据
0x1000 -> 0x12 (高位字节)
0x1001 -> 0x34
0x1002 -> 0x56
0x1003 -> 0x78 (低位字节)

  

  小端字节序(Little-Endian):在小端字节序中,数据的低位字节存储在低位地址上,而数据的高位字节存储在高位地址上。这种方式与大端字节序相反,但是在实际应用中也有很多优点,例如可以方便地进行低位对齐。

  存储方式:同样以32位整数0x12345678为例,其内存地址为0x1000。在小端字节序的系统中,该整数的存储方式如下:

地址            数据
0x1000 -> 0x78 (低位字节)
0x1001 -> 0x56
0x1002 -> 0x34
0x1003 -> 0x12 (高位字节)

  

  大小端的实现原理和存储方式主要体现在多字节数据在内存中的排列顺序。大端字节序将高位字节存储在低地址,而小端字节序将低位字节存储在低地址。不同的处理器架构可能采用不同的字节序,因此在进行跨平台数据交换时需要注意字节序的转换。两种字节序的区别在于字节的存储顺序,而不是位的存储顺序。在多字节数据类型(例如整数、浮点数等)存储时,其字节序决定了字节在内存中的排列顺序。

  下面是一个示意图,展示了一个32位整型数在大端和小端字节序下的存储方式:

大端字节序:
0x12345678
+--------+
| 12 | 34|
+--------+
| 56 | 78|
+--------+

小端字节序:
0x12345678
+--------+
| 78 | 56|
+--------+
| 34 | 12|
+--------+

  

4,不同架构的字节序规则

  不同的处理器架构可能采用不同的字节序规则。以下是一些常见处理器架构及其字节序规则:

  Intel x86/x64(IA-32/IA-64): 字节序规则:小端(Little-endian) 说明:Intel x86和x64架构处理器广泛应用于个人计算机和服务器领域。这些处理器采用小端字节序,将低位字节存储在低地址。

  ARM: 字节序规则:大小端可配置(Configurable Endianness) 说明:ARM处理器广泛应用于嵌入式系统和移动设备。ARM架构支持大小端可配置,系统设计者可以根据实际需求选择合适的字节序。大多数情况下,ARM处理器默认采用小端字节序。

  MIPS: 字节序规则:大小端可配置(Configurable Endianness) 说明:MIPS处理器应用于嵌入式系统、网络设备和游戏机等领域。MIPS架构支持大小端可配置,允许系统设计者根据需求选择字节序。通常情况下,MIPS处理器默认采用大端字节序。

  PowerPC: 字节序规则:大小端可配置(Configurable Endianness) 说明:PowerPC处理器应用于嵌入式系统、服务器和游戏机等领域。PowerPC架构支持大小端可配置,允许系统设计者根据需求选择字节序。通常情况下,PowerPC处理器默认采用大端字节序。

  Motorola 68000: 字节序规则:大端(Big-endian) 说明:Motorola 68000系列处理器曾广泛应用于个人计算机、游戏机和嵌入式系统等领域。这些处理器采用大端字节序,将高位字节存储在低地址。

  SPARC: 字节序规则:大端(Big-endian) 说明:SPARC处理器主要应用于高性能计算和服务器领域。SPARC架构采用大端字节序,将高位字节存储在低地址。

  需要注意的是,不同处理器架构的字节序规则可能会影响跨平台数据交换。在进行数据交换时,需要注意字节序的转换,以确保数据的正确性。许多编程语言和库提供了跨平台的字节序转换功能,以便在不同字节序的系统之间进行数据交换。

  简单将上面内容整理一下(方便直接看结论的童靴):

大小端 CPU
Big Endian PowerPC, MIPS, Mac OS, IBM , Sun, Mototola 68000, SPARC
Little Endian x86, x64, DEC, Windows

 

4.1  如何判断机器的字节序

  遇到大小端的问题,我们如何解决呢,首先就是判断机器的字节序(是大端字节序还是小端字节序),然后进行转换。

  给一个C++判断机器字节序的代码:

// Judge the endian of the local system
inline bool isLittleEndian() {
union {
uint32_t i;
char c[4];
} test = {0x01020304};
return test.c[0] == 0x04;
}

  或者下面例子:

#include <iostream>

// 判断机器字节序的函数
bool isLittleEndian() {
    int num = 1;
    char *ptr = reinterpret_cast<char*>(&num);
    return *ptr == 1;
}

int main() {
    if (isLittleEndian()) {
        std::cout << "This machine is Little-endian." << std::endl;
    } else {
        std::cout << "This machine is Big-endian." << std::endl;
    }
    return 0;
}

  下面是一个转换大小端字节序的例子,比如你的机器需要大端,所以处理不同操作系统的时候,你需要考虑先判断系统字节序的,然后不同的需要转换,毕竟我们上面也提到了不同系统字节序不同。

#include <iostream>

// 转换16位整数的字节序
uint16_t swapEndian16(uint16_t value) {
    return (value << 8) | (value >> 8);
}

// 转换32位整数的字节序
uint32_t swapEndian32(uint32_t value) {
    return ((value << 24) & 0xFF000000) |
           ((value << 8) & 0x00FF0000) |
           ((value >> 8) & 0x0000FF00) |
           ((value >> 24) & 0x000000FF);
}

// 转换64位整数的字节序
uint64_t swapEndian64(uint64_t value) {
    return ((value << 56) & 0xFF00000000000000) |
           ((value << 40) & 0x00FF000000000000) |
           ((value << 24) & 0x0000FF0000000000) |
           ((value << 8) & 0x000000FF00000000) |
           ((value >> 8) & 0x00000000FF000000) |
           ((value >> 24) & 0x0000000000FF0000) |
           ((value >> 40) & 0x000000000000FF00) |
           ((value >> 56) & 0x00000000000000FF);
}

int main() {
    uint16_t num16 = 0x1234;
    uint32_t num32 = 0x12345678;
    uint64_t num64 = 0x123456789ABCDEF0;

    std::cout << "Original 16-bit value: " << std::hex << num16 << std::endl;
    std::cout << "Swapped 16-bit value: " << std::hex << swapEndian16(num16) << std::endl;

    std::cout << "Original 32-bit value: " << std::hex << num32 << std::endl;
    std::cout << "Swapped 32-bit value: " << std::hex << swapEndian32(num32) << std::endl;

    std::cout << "Original 64-bit value: " << std::hex << num64 << std::endl;
    std::cout << "Swapped 64-bit value: " << std::hex << swapEndian64(num64) << std::endl;

    return 0;
}

  上面的示例展示了如何在C++中判断机器的字节序以及如何转换大小端字节序。在实际应用中,可能大家需要根据自己的需求对代码进行调整和优化,我自己也是。(当然如果使用python,可能更方便)

5,应用场景

  大小端字节序在计算机系统中有很多应用场景。以下是一些常见的应用场景:
  1. 跨平台数据交换: 当不同字节序的计算机系统需要交换数据时,需要进行字节序转换以确保数据的正确性。例如,网络协议中的数据包在发送和接收时需要进行字节序转换。大多数网络协议(如TCP/IP)采用大端字节序(网络字节序)作为标准。因此,在发送数据时,小端字节序的系统需要将数据转换为大端字节序;在接收数据时,需要将大端字节序的数据转换为小端字节序。
  2. 文件格式: 许多文件格式规定了数据的字节序。例如,BMP图像文件格式规定了数据的字节序。在处理这些文件时,需要根据文件格式的要求进行字节序转换,以确保数据的正确性。
  3. 数据库存储: 在数据库中存储多字节整数时,可能需要考虑字节序问题。不同的数据库系统可能采用不同的字节序。在进行数据迁移或备份时,需要注意字节序的转换。
  4. 外部设备通信: 在与外部设备(如传感器、控制器等)通信时,可能需要进行字节序转换。外部设备可能采用不同的字节序,因此在发送和接收数据时需要进行字节序转换以确保数据的正确性。
  5. 二进制数据处理: 在处理二进制数据(如加密、压缩等)时,可能需要考虑字节序问题。不同的算法可能对字节序有不同的要求。在实现这些算法时,需要根据算法的要求进行字节序转换。
  总之,大小端字节序在计算机系统中有很多应用场景。在处理跨平台数据交换、文件格式、数据库存储、外部设备通信和二进制数据处理等问题时,需要注意字节序的转换,以确保数据的正确性。

与计算机系统中的大端模式和小端模式相似的内容:

计算机系统中的大端模式和小端模式

最近工作中有用到一个知识点,就是大小端,当然这是一个小的知识点,为什么写一个博文呢,我其实是想测试一下chatGPT,所以我开始将自己的想法告诉这个chatbot,让他给我一些写博文的建议,并且给我解答了一些疑惑,今天将自己的学习笔记整理出来展示给大家(by the way,一个有用的搜索引擎和ch

探究:初学者编程语言的选择

| 日期 | 修改人 | 修改内容 | | | | | | 2023年2月12日 | 北极的大企鹅 |添加了C语言的新比喻 | 前景提要 很多初学者面临的最多的问题就是编程语言的选择问题,一旦你接触编程,无论任何人都会给你提到一个问题,说你要选择一门编程语言学习,才能在后续的计算机学习中取得成绩,但

[转帖]CPU缓存行

https://www.jianshu.com/p/e338b550850f CPU缓存 执行程序是靠运行CPU执行主存中代码,但是CPU和主存的速度差异是非常大的,为了降低这种差距,在架构中使用了CPU缓存,现在的计算机架构中普遍使用了缓存,分为一级缓存,二级缓存,还有一些具备三级缓存,我们可以看

整理并发布本科四年的课程资料

可恶,我的本科课程资料 repo 已发布半年,但是发现的人实在是太少了。 如此高质量的课程资料,埋没在互联网中实在可惜,于是写一篇博客引流→ tag: 东南大学 | 计算机科学与技术 | 09 系 | 2019 级 | 专业课 | 往年真题 | 课程笔记 | 期末大作业 数据结构 | 计算机组成原理

第124篇: 期约Promise基本方法

好家伙,本篇为《JS高级程序设计》第十章“期约与异步函数”学习笔记 1.异步编程 同步行为和异步行为的对立统一是计算机科学的一个基本概念。 特别是在 JavaScript 这种单线程事 件循环模型中,同步操作与异步操作更是代码所要依赖的核心机制。 异步行为是为了优化因计算量大而 时间长的操作。如果在

[转帖]Redis是的缓存特征及类型

文章目录 缓存特征缓存处理请求的两种情况缓存的类型只读缓存读写缓存 缓存特征 一个系统中的不同层之间的访问速度不一样,所以我们才需要缓存,这样就可以把一些需要频繁访问的数据放在缓存中,以加快它们的访问速度。 计算机系统中的三层存储结构,以及它们各自的常用容量和访问性能 计算机系统中,默认有两种缓存:

探索文件系统:高效、可靠的文件管理与访问机制

本篇文章探索了文件系统的功能规划,着重讨论了文件存储、索引节点和目录项的管理、缓存策略以及文件数据的存储等方面。文件系统作为计算机系统中重要的组成部分,对于实现高效、可靠的文件管理与访问机制至关重要。通过深入了解文件系统的基本单位、元信息记录和目录结构,我们可以更好地理解文件系统的工作原理,本文旨在为读者提供对文件系统功能规划的全面认识,以帮助他们更好地理解和应用文件系统相关的技术。

机器学习-周志华

第一章 绪论 机器学习: 致力于研究如何通过计算的手段,利用经验来改善系统自身的性能。在计算机系统中,“经验”通常以“数据“形式存在,因此,机器学习所研究的主要内容,是关于在计算机上从数据中产生”模型“的算法,即”学习算法“。有了学习算法,我们把经验数据提供给它,他就能基于这些数据产生模型;在面对新

Gossip in Hyperledger Fabric

1. Gossip协议基础 1.1 什么是分布式系统 分布式系统(Distributed System)是由多台计算机或计算节点组成的计算机系统,这些计算节点通过网络连接在一起,并协同工作以完成共同的任务或提供服务。与单一计算机系统不同,分布式系统中的计算节点可以分布在不同的地理位置。 以下是分布式

【0day漏洞复现】北京慧飒科技有限责任公司WEB VIDEO PLATFORM存在未授权访问漏洞

阅读须知 花果山的技术文章仅供参考,此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等(包括但不限于)进行检测或维护参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失,均由使用者本人负责。本文所提供的工具仅用于学习,禁止用于