数据存储:大端和小端

article/2025/9/24 21:50:50

目录

字节序

大端和小端

大端小端测试

写入测试

字节码文件的大小端


      前面说到,像C/C++这类语言编写的程序,它们被编译后,直接转换成了对应平台上的可被CPU直接运行的机器指令,转换之后,原本语言中的数据结构,例如结构体信息都被替换掉了,换成了各个数据在内存中的地址和偏移量,操作系统并不知道原来的数据的类型,例如一段C程序被编译成汇编语言后,结构体信息被拆成了一条条对内存操作的指令,一个个变量都变成了首地址,原本的C代码结构不复存在。Java则不同,我们知道Java语言因为跨平台性的原因,程序在转变成机器可执行的指令之前,需要先翻译成中间语言-字节码文件,字节码有它特定的结构,会将Java中的类型结构信息存储起来,待JVM加载字节码文件时,会保存所有的元数据,元数据也就是原始的类型信息,上篇日志中opp-klass模型里的instanceKlass,它保存了Java类的所有信息,例如里面的方法和变量,也正因为了有了这种机制,JVM才支持“反射”,运行Java程序在运行期间能够动态获取实例对象的类型,方法等信息。

 

字节序

      Java语言实现跨平台性,执行前先被编译成统一字节码文件,.class文件与平台无关,只与JVM有关,之后在不同的操作系统环境(Linux,Windows之类)下由不同的JVM来解释执行.class文件,虽然同一Java程序生成的字节码文件相同,但数据在不同平台上的存储方式是不同的。我们知道,字节数据在计算机中存储,或者在网络中收发,是要按照一定的顺序的,这种字节输入输出和存储的顺序,即字节序,在不同的硬件环境中有所不同。拿网络中收发数据包来举例,在传输层发送的数据包如果太大,就会被拆分成多个包,每一个小的数据包都有序号,接收方接收到每一个包都要按照顺序组装成一个完整的包,这样即使按顺序先发出去的1号包没有被先接收,而是先接收到2号包,接收方也会等待,待1号包接收后先将其递交给上层,如果不严格按照顺序收发,存储,那么通信双方发送的数据就无法正确译码。

 

大端和小端

      前面说到不同的操作平台上,数据存储在内存和磁盘,或者寄存器上的格式是不同的,具体表现在存储顺序不同,通常分为两种方式,大端Big-Endian和小端Little-Endian方式,大端方式即将数据中高位的字节存放在内存中的低地址处,数据中低位的字节存放在内存中的高地址处,小端方式则相反,高位字节存放在高地址,低位字节存放在低地址。上面举例的网络中收发数据包,因为使用TCP/IP协议的缘故,字节数据使用大端的方式。

      举个例子看大端和小端的存储方式,假设有一个十六进制数据0x12345678,占4个字节,要存储到内存地址0x004060处,使用大端的方式,即数据的高位字节存放到内存地址的低地址端,低位字节放到高地址端,那么存放的对应关系如下:

内存地址

0x004060

0x004061

0x004062

0x004063

数据值

12

34

56

78

      可以看到, 数据字节增长方向和内存地址增长方向是相同的,这种方式比较方便我们程序员阅读,而如果使用小端方式存储,它的对应关系是这样:

内存地址

0x004060

0x004061

0x004062

0x004063

数据值

78

56

34

12

相比大端来说不易于程序员阅读。

      产生大端小端存储方式的原因是寄存器的宽度,计算机内存存储单元为1个字节,现在的CPU普遍都是32位或64位,意味着其可以一次传输4字节或8字节的数据,,大多数寄存器的宽度也不止一个字节,所以寄存器可以一次读出多个连续内存存储单元的值,也能一次往多个连续存储单元写入数据。我们知道,数据不能直接在内存之间传输,必须通过寄存器中转,例如我们平时写的代码int a = b;它就是先把内存中b的数据读取到寄存器里,再把寄存器里的数据放到a的内存位置。假设我们现在有一个2字节的十六进制数据0x0205,十进制表示517,数据的高字节为02,低字节为05,将它放到寄存器里,如果寄存器采用大端方式存储,即02存放到低地址位,05存放到高地址为,那么数据在寄存器中的值就是0x0205,这个没什么问题,但如果寄存器采用小端方式存储,那么0x0205存储到寄存器后,值就变为0x0502,其对应的十进制就变成了1282。

 

大端小端测试

我们可以用个简单的测试程序来看看自己的硬件CPU是大端还是小端存储:

      例子很简单,通过char c = *p拿到变量x的地址,如果系统采用的是小端存储方式,那么地址的低位会被存放在高地址处,x的首地址就是0x1,否则x的首地址就是0。从输出结果可以看到,我这台计算机采用的是小端方式存储。

 

写入测试

      上面的测试程序是我们向操作系统申请空间,接下来用另一个例子,我们往内存中写入数据,看看计算机是不是也会以小端方式帮我们存储:

      上面这个例子中,我们向一个数组里写入两个字节的数据,0x10和0x20,然后通过char *p = data拿到data数组的首地址,强制类型转换short*指针,最后转换成short类型,如果你的CPU使用的是大端方式存储,那么写入数组的数据从左到右,也就是从低地址位到高地址位的排列顺序是0x1020,十进制表示为4128。如果采用的是小端方式,那么高字节位数据存放在高地址处,最后存储的数据变成0x2010,对应十进制8208。

 

字节码文件的大小端

      上面两个例子的运行结果,都表现出在我的计算机上使用的是小端方式存储,但在Java程序编译得到的字节码文件里,使用的全部都是大端方式,例如JVM在加载字节码文件时,首先会检查最前面4个字节的魔数,它是一个固定值0xCAFEBABE,它的写入顺序就是0xCA、0XFE、0xBA、0xBE。数据写入没有问题,因为它是由Java语言完成,使用大端方式,但是读取时就有地方要注意了,JVM使用C和C++编写,它们采用大端还是小端是取决于当前的硬件平台,当其读取.class字节码文件时,魔数在C语言中可以用int型表示,如果当前环境采用了小端方式存储,那么魔数的读取就会得到0xBE、0xBA、0xFE、0xCA,此时读到的魔数就和上面的Java程序相反了,会导致JVM校验魔数失败,停止加载.class字节码文件。如果是使用Java编写的编译器,就不需要对数据字节序进行处理,但JVM是C和C++编写的,如果运行在了采用小端方式存储的平台上,那就要对字节序进行反转处理了,对字节序进行反转处理。

      以前我写网络编程的时候也才踩过这类坑,服务器连不上,后来发现要将地址逆序。


http://chatgpt.dhexx.cn/article/2YIuisZI.shtml

相关文章

大端和小端传输字节序

大端和小端 在计算机中是以字节为单位,每一个地址对应一个字节,一个字节8bit。在C中,除了8bit的char以外,还有16bit的short,32位的int,64位long,当然具体要由编译器决定,可以通过si…

大端字节序和小端字节序

字节序,即字节在电脑中存放时的序列与输入(输出)时的序列是先到的在前还是后到的在前。 -- 转自:字节序_百度百科 (baidu.com) 在几乎所有的平台上,多字节对象都被存储为连续的字节序列。例如在 C 语言中,一…

简单理解大端小端

大端和小端是计算机写内存的习惯。就如人类写文章时的顺序一般,现代人从左往右,古人却是竖书成行(自上而下写满一行后,再自右向左换行。);有些计算机规定从左往右写内存,有些规定从右往左写内存…

java 为什么用大端_Java中的大端和小端

Java整型的字节序是() A.Little-Endian(小端) B.Big-Endian(大端) C.由运行程序的CPU决定 D.由编译程序的CPU决定 对于大小端,我估计肯定有很多开发人员跟我一样都没听过 由于Java是跨平台的,JVM为我们屏蔽了大量的底层细节和复杂性,导致在平…

存储模型:大端和小端

前言: 计算机操作系统中存储信息都是以字节为单位,每个地址单元对应 1 个字节。 1 个字节为 8 bits,对于某些32 位处理器而言,char类型数据占用 1 个字节的空间,short 占用2个字节,int 占用4个字节。而这…

操作系统之大端小端

1. 什么是大端,什么是小端: 所谓的大端模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中; 所谓的小端模式,是指数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地…

二进制、16进制、大端小端

16进制的使用 在开发过程中,写文件是常有的事,如果写的内容是文本,随便用一个记事本软件打开即可查看内容是否正确,如果写的是音频文件,就要用音频播放器来查看,如果是视频文件,就要用视频播放…

网络传输大端序_大端、小端与网络字节序

大端(Big-Endian),小端(Little-Endian)以及网络字节序的概念在编程中经常会遇到。网络字节序(Network Byte Order)一般是指大端(Big-Endian,对大部分网络传输协议而言)传输,大端小端的概念是面向多字节数据类型的存储方式定义的,小…

677-大端模式和小端模式详解

1、大端和小端核心是什么? 大端模式和小端是实际的字节顺序和存储的地址顺序对应关系的两种模式,总结如下: 大端模式:低地址对应高字节 小端模式:低地址对应低字节 不管是大端还是小端模式,我们在读取和存…

大端小端详解

转载:大端小端详解 1>"大端" "小端"的来源 关于大端小端名词的由来,网传有一个有趣的故事,可以追溯到1726年的Jonathan Swift的《格列佛游记》,其中一篇讲到有两个国家因为吃鸡蛋究竟是先打破较大的一端…

大端序发送数据

需要发送数字 151510 大端序发送就是 :00 02 4F D6 string smallData textBox1.Text;//小端数据if (smallData ""){MessageBox.Show("请输入初始里程", "错误",MessageBoxButtons.OK, MessageBoxIcon.Exclamation);textBox1.Text …

c语言之大端小端问题

这就是字节序问题:数据在计算机内存中存储或者网络传输时各字节的存储顺序 通常来说就分为两种情况: 一种是大端(big-endian):高字节(高位)存放在低地址,低字节(低位)存在高地址 另外一种小端(little-endian):高位存放…

数据存储:大端小端

文章目录 问题起源大端小端大端小端优劣符合人类阅读方式数据类型转换符号位的识别 参考资料 曾经辨析和了解过大端小端,但是到了实际应用中还是比较模糊。整理一些资料文章,在此记录。 问题起源 在计算机的使用以及现代很多的嵌入式设备中,…

大端与小端

一.大小端介绍 “大端”和“小端”表示多字节值的哪一端存储在该值的起始地址处。小端存储在起始地址处,即是小短字节序;大端存储在起始地址处,即是大端字节序。 大端存储模式:数据的低位保存在内存中的高地址中,数据…

大端和小端的含义及判断代码

1、概述 在计算机系统中,数据都是以字节进行存储的,每个地址单元对应一个字节,每个字节都是8位(bit)。但是C除了char和bool之外,还有其它多字节类型。怎样存储多字节的数据就分为了大端和小端。字节序只和…

C语言基础 —大端和小端

大端和小端 1、什么是大端和小端2、为什么会有大端和小端3、怎样判断是大端还是小端 1、什么是大端和小端 大端模式:就是 高位字节 存放在内存的 低地址端,低位字节 存放在内存的 高地址端 小端模式:就是 低字节存 放在内存的 低地址端&…

大端和小端的区别和判断

1.概念 大端模式(big endian):数据的高位字节保存在内存的低地址中,而低位字节保存在内存的高地址中。 小端模式(little endian):数据的高位字节保存在内存的高地址中,而低位字节保存在内存的低地址中。 问:什么是高…

什么是大端和小端

大端(存储)模式:是指数据的低位保存在内存的高地址中,而数据的高位保存在低地址中; 小端(存储)模式:是指数据的低位保存在内存的低地址中,而数据的高位保存在高地址中。 …

大端、小端的前世今生

什么是大端、小端? BigEndian(大端):低字节在高内存地址 LittleEndian(小端):低字节在低内存地址 所谓大端小端,也就是看低字节在高内存地址还是低内存地址,也就是看低字节在前还是高字节在前,低字节在前…

数据存储:小端模式和大端模式——终于搞明白了!!!

首先要记住:读数据永远是从低地址开始的!!! 正文开始 什么是低地址、高地址? 地址编号小的是低地址,地址编号大的是高地址 什么是数据的低位、高位? 小端模式 数据的低位放在低地址空间&am…