首页 > 其他分享 >数据存储的大端和小端

数据存储的大端和小端

时间:2024-11-28 10:22:50浏览次数:6  
标签:小端 存储 顺序 字节 地址 大端

在计算机系统中,数据的存储方式对性能、兼容性以及编程有着深远的影响。

现代计算机都是以字节编址的,即每个地址下标对应一个字节,如果我们要以地址下标指代一个多字节数据(如 4 字节的 int),就需要考虑四个字节的排列顺序。大端(Big Endian)和小端(Little Endian)是两种常见的数据存储顺序,它们决定了多字节数据在内存中的排列方式。

大端和小端

大端(Big Endian)小端(Little Endian)是指多字节数据(如32位或64位整数)在计算机内存中的存储顺序。

  • 大端模式(Big Endian):在这种模式下,数据的高字节存储在低地址处,低字节存储在高地址处。例如,一个32位整数0x12345678在内存中的存储顺序是:

    地址    数据
    0x00    0x12  (高字节)
    0x01    0x34
    0x02    0x56
    0x03    0x78  (低字节)
    
  • 小端模式(Little Endian):在小端模式下,数据的低字节存储在低地址处,高字节存储在高地址处。以相同的32位整数0x12345678为例,在内存中的存储顺序是:

    地址    数据
    0x00    0x78  (低字节)
    0x01    0x56
    0x02    0x34
    0x03    0x12  (高字节)
    

从以上示例可以看出,字节的排列顺序在两种模式中是完全相反的。

排列方式

在实际的计算机硬件架构中,处理器通过指定的内存地址访问数据。由于大端和小端存储顺序的不同,处理器在执行指令时需要根据内存中数据的存储顺序来进行适当的读取或写入操作。

考虑以下C语言代码,演示如何将一个32位整数存储到内存中:

#include <stdio.h>

int main() {
    int num = 0x12345678;
    unsigned char *byte_ptr = (unsigned char *)&num;

    for (int i = 0; i < sizeof(num); i++) {
        printf("Byte %d: 0x%02x\n", i, byte_ptr[i]);
    }

    return 0;
}

大端模式下,程序将输出:

Byte 0: 0x12
Byte 1: 0x34
Byte 2: 0x56
Byte 3: 0x78

而在小端模式下,程序将输出:

Byte 0: 0x78
Byte 1: 0x56
Byte 2: 0x34
Byte 3: 0x12

可以看出,地址按字节编址,一个地址\(p\)若指示某字节,当然指的是字节本身;若指代一个 int,则指代该 int 的 \(p, p+1, p+2, p+3\) 四个字节,大端用 \(p\) 存储最高位,小端则反过来。当然每个字节内还是按顺序存储的。我们还可以看出,在大端模式下,符号位(最高位)存储在最低地址(最先被读取的字节)上,是第一个字节的最高位,这样只需要访问最低地址的字节(即高位字节)就可以立刻判断符号。而小端共容易截断,因为低位字节存储在低地址,所以当你需要对多字节数据进行截断(比如丢弃高位),你可以直接访问低地址的字节。

大端小端仅对数据有效,取指令时若从\(p\)取值,完整的指令一定是从低到高,但指令中的多字节操作数仍遵循大端小端规律。

实际编程中的影响

对于大部分程序员而言,大端和小端的概念通常不会直接影响日常的开发工作,尤其是在现代编程语言中,编译器和操作系统往往会抽象掉这一层细节。然而,在一些低级编程(如操作系统开发、嵌入式开发、网络协议栈开发等)中,了解并正确处理字节顺序变得至关重要。

  • 在跨平台的应用程序开发中,尤其是当涉及到二进制数据存储和传输时,确保数据的字节顺序一致是至关重要的。常见的做法是使用网络字节顺序(通常是大端顺序)来进行数据交换。例如,TCP/IP协议中的数据传输就是以大端顺序进行的。因此,在网络编程中,经常需要使用诸如htonl()ntohl()这样的函数来进行字节序的转换。

  • 许多文件格式(如图像文件、音频文件等)可能规定了字节顺序。在这种情况下,读取文件时需要正确解释数据的字节序列,否则将导致数据的误解读。

  • 在现代处理器上,大端和小端的性能差异通常微乎其微。但在一些嵌入式系统中,硬件支持某种字节顺序可能会影响数据访问的效率。例如,某些处理器在读取内存时,可能更倾向于优化小端顺序的访问。

历史沿革

字节顺序的选择,最初源自计算机硬件设计的不同。不同的处理器设计对字节顺序有不同的偏好。例如,早期的IBM大型机采用了大端模式,而X86架构的个人计算机则使用了小端模式。

最初,字节顺序的选择并没有严格的标准。随着不同架构的出现,不同的硬件平台采用了各自不同的字节序约定。这种差异影响了软件的移植性,尤其是在需要对不同平台进行数据交换时。

为什么个人PC总是小端?

在你的笔记本电脑上测试上述代码,结果一定是小端,这是因为个人计算机(PC)大多数使用x86架构,而x86处理器都是小端架构。这一选择的历史原因与硬件设计紧密相关。x86架构最早由Intel设计,Intel选择了小端模式。小端的选择在当时是为了简化硬件设计,尤其是在处理器对数据访问的优化方面,小端顺序可以更高效地处理低地址部分的字节。

随着x86架构的普及,个人PC几乎都采用了小端模式,成为了行业的标准。虽然现代计算机处理器(如AMD64、ARM等)支持多种字节顺序,但由于向下兼容的原因,个人PC仍然保留了小端顺序。

哪些机器使用大端和小端?

  • 大端:早期的PowerPC、SPARC、MIPS等架构采用了大端模式。许多嵌入式系统和网络设备(如路由器、交换机等)也使用大端模式,特别是在需要与其他大端系统(如网络协议、某些数据库格式)进行数据交换时。

  • 小端:Intel的x86和x86-64架构(也就是个人PC的主流架构)使用小端模式。此外,许多现代的ARM处理器也支持小端模式。

有些处理器(如某些ARM架构)甚至可以在运行时切换大端和小端模式,这种灵活性有助于它们适应不同的应用场景。

标签:小端,存储,顺序,字节,地址,大端
From: https://www.cnblogs.com/ofnoname/p/18573715

相关文章

  • Flink 热存储维表 使用 Guava Cache 减轻访问压力
    目录背景GuavaCache简介实现方案1.项目依赖2.GuavaCache集成到Flink(1)定义Cache(2)使用Cache优化维表查询3.应用运行效果(1)维表查询逻辑优化(2)减少存储压力GuavaCache配置优化总结背景在实时计算场景中,Flink应用中经常需要通过维表进行维......
  • GaussDB数据库存储过程介绍
    @目录一、前言二、GaussDB中的定义三、存储过程的使用场景四、存储过程的使用优缺点五、存储过程的示例及示例解析1、GaussDB存储过程语法格式2、GaussDB存储过程语法示例3、存储过程的调用方法七、总结一、前言华为云数据库GaussDB是一款高性能、高安全性的云原生数据库,在数据......
  • 芯片基础详解:总线、256字节随机存储器、模式选择器(指令解码器)、条件判断器
    总线总线:从正确的输入端将数值复制到正确的输出端。总线电路------------------------------------------------------------------------------------------256字节随机存储器256字节随机存储器电路---------------------------------------------------------------......
  • GaussDB数据库存储过程介绍
    @目录一、前言二、GaussDB中的定义三、存储过程的使用场景四、存储过程的使用优缺点五、存储过程的示例及示例解析1、GaussDB存储过程语法格式2、GaussDB存储过程语法示例3、存储过程的调用方法七、总结一、前言华为云数据库GaussDB是一款高性能、高安全性的云原生数据库,在数据......
  • 本地存储的生命周期是什么?
    在前端开发中,本地存储主要指的是浏览器提供的存储机制,主要有以下几种,它们的生命周期各不相同:localStorage(本地存储):除非被手动清除(例如,用户清除浏览器数据、通过JavaScript代码清除),否则localStorage中的数据会永久保存在用户的浏览器中。即使浏览器关闭或电脑重启,数据......
  • 为什么提倡利用多个域名来存储网站的资源?
    在前端开发中,提倡利用多个域名存储网站资源主要基于以下几个原因:提升浏览器并发连接数:浏览器对同一域名的并发连接数有限制(通常为6-8个,具体取决于浏览器和版本)。使用多个域名可以突破这个限制,允许浏览器同时下载更多资源,从而加快页面加载速度。例如,可以将图片资源放在img......
  • Docker - Minio对象存储部署
    Minio是一个基于ApacheLicensev2.0开源协议的对象存储服务。非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。集群部署也是非常的简单,本篇文章只讨论单机部署,集群有需要后续跟进......
  • python连接操作oss对象存储
    用python调试一下oss对象存储。一开始用的oss2库,发现不行。用boto3库才可以,说明我的对象存储是和AWS兼容的,并不是基于阿里的oss.importboto3frombotocore.exceptionsimportNoCredentialsError,PartialCredentialsError#设置您的AccessKey和SecretKeyaccess_key_id......
  • minio对象存储 -图床 -图片上传 -头像
    初次发布于我的个人文档参考:1,MINIO在java中的使用2.MinIOLinux官方文档1.利用1panel安装minio图片上传等服务依赖于对象存储服务,本文就以开源对象储存minio为例简单介绍。推荐使用linux版本的minio,只需在1panel应用商城傻瓜式安装即可。记得记好你的root账户用户名和密码......
  • RX23E-B系列微控制器是工业传感器设备的理想选择!R5F523E5B介绍,EFR32BG13P732F512GM48-
    RX23E-B系列微控制器具有内置模拟前端(AFE),是工业传感器设备的理想选择。与上一代的RX23E-A相比,RX23E-B的24位DeltaSigma模/数转换器在高速性能和噪声性能上均得到了改善。最大数据速率为125kSPS,这对于DeltaSigma模/数转换器来说速度很快,比RX23E-A快8倍。RMS......