字节序详解

C语言的位操作 - bit 、byte的清零,置1,提取,判断 首先,以下是按位运算符:在嵌入式编程中,常常需要对一些寄存器进行配置,有的情况下需要改变一个字节中的某一位或者几位,但是又不想改变其它位原有的值,这时就可以使用按位运算符进行操作。下面进行举例说明,假如有一个8位的TEST寄存器:bit1~bit7,如果这高7位没有用到的话,这么设置没有什么影响;但是,如果这7位正在被使用,结果就不是我们想要的了。在这种情况下,我们就可以借用按位操作运算符进行配置。 阅读详情


1. 首先建立如下的物理内存概念(独立于字节序)


如下面的图-1所示,内存中有连续的4个字节,左边是低地址,右边是高地址。

我们这里假设4个字节的地址分别是0,1,2,3。



低地址                                                      高地址

|<--------------------------bits-------------------------------->
0                                                             31

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|               |               |               |               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

        0               1               2               3      
|<--------------------------bytes------------------------------->


                            图-1


接下来,我们要进一步引入bit地址的概念。

我们认为,每个bit也有地址。并且,与字节的地址顺序一样,左边是低地址,右边是高地址。

这样一来,左边是低地址的字节,右边是高地址的字节。

在每一个字节内部呢,左边是低地址的bit,右边是高地址的bit。

好了,现在我们建立了这样的物理内存概念。

注意,这个物理内存概念是独立与字节序的,并且是独立与cpu类型、内存类型的。

也就是说,不管你是什么系统,这个概念都是一样的。


2.  字节序的概念

假设有一个整数,占据了上图中的一片连续的bit位。那么这个整数的数值是多少呢?

这就取决于cpu的字节序了。

大字节序机器:低地址的bit是高有效位,高地址的bit是低有效位

小字节序机器:低地址的bit是低有效位,高地址的bit是高有效位



3. 存储空间的分配(独立于字节序)

typedef struct

{

    char a;

    char b1:3;

    char b2:5;

    uint16_t  c1:6;

    uint16_t  c2:10;

} t_my_type;


上述C语言定义的结构体中,各成员所占的内存空间是如何分配的呢?

答案是,按成员定义的顺序,从低地址向高地址依次分配空间。

注意,这种分配方式是独立与cpu类型、内存类型的。

也就是说,不管你是什么系统,分配方式都是如此。

按照上述分配方式,上述结构的各成员在内存中的分布如下面图-2所示:


低地址                                                      高地址
|<--------------------------bits-------------------------------->
0                                                             31


+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|       a       |  b1 |  b2     |     c1    |    c2             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+


        0               1               2               3      
|<--------------------------bytes------------------------------->


                            图-2


4.  数据的网络发送

按照字节地址从低到高的顺序发送:低地址的字节在前,高地址的字节在后。

如果再细化到bit的话,则同一个字节内:高有效位的bit在前,低有效位的bit在后。

这样一来,对于每一个字节内的bit位的发送顺序,大小字节序的机器就有如下区别了:

大字节序机器:按地址由低到高的顺序发送bit位

小字节序机器:按地址由高到低的顺序发送bit位


5.  数据的网络接收

先到达的字节为低地址字节,后到达的字节为高地址字节。

同样,如果再细化到bit的话,则同一个字节内:高有效位的bit先到达,低有效位的bit后到达。

这样一来,对于每一个字节内的bit位的存储位置,大小字节序的机器就有如下区别了:

大字节序机器:按bit到达顺序从低地址向高地址存储

小字节序机器:按bit到达顺序从高地址向低地址存储


6. 应用

由于gcc工具链自然知道自己是为什么cpu编译代码,因此工具链自身是包含了目标cpu的字节序信息的。

对于程序员而言,只要包含endian.h,然后通过检查__BYTE_ORDER宏的值,就能知道当前是为什么字节序的cpu生成代码。

下面举个小例子,说明主机间通过网络通信时,如何正确的处理字节序问题。

假设两台主机(字节序可能相同,也可能不同),需要通过网络传递一个结构化的信息,信息由a,b,c,d这4个整数构成。

那么,此结构可以定义成如下形式。

#include <stdint.h>
#include <endian.h>
typedef struct
{
    uint16_t   a;
    uint32_t   b;
#if __BYTE_ORDER == __BIG_ENDIAN
    uint16_t  c:3;
    uint16_t  d:13;
#else  if  __BYTE_ORDER == __LITTLE_ENDIAN
    uint16_t  d:13;
    uint16_t  c:3;
#else
#error  can not get byte order info
#endif
} __attribute__((packed)) t_msg;



发送消息时,按如下方式封装此结构(不管封装机器字节序如何)

#include <arpa/inet.h>
t_msg   the_msg;
uint16_t *p16=(void *)&the_msg + sizeof(the_msg.a) + sizeof(the_msg.b);   //p16指向成员b后面的内容
the_msg.a = htons(1234);
the_msg.b = htonl(1234);
the_msg.c = 5;
the_msg.d = 8;
*p16 = htons(*p16);
//封装完毕,可以发送了



收到消息时,按如下方式取出此结构中的数值(不管封装机器字节序如何)

#include <arpa/inet.h>
t_msg   the_msg;
//接收消息到the_msg变量中。
uint16_t *p16=(void *)&the_msg + sizeof(the_msg.a) + sizeof(the_msg.b);   //p16指向成员b后面的内容
the_msg.a  = ntohs(the_msg.a);
the_msg.b  = ntohl(the_msg.b);
*p16 = ntohs(*p16);
//好了,现在the_msg中的成员,都变成主机序了,可以直接使用了


最后,再看看如下Linux源码中tcp头的定义,再结合字节序转换函数的功能作用,对于字节序您是否有所领悟呢:)

struct tcphdr {
__be16 source;
__be16 dest;
__be32 seq;
__be32 ack_seq;
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u16 res1:4,
doff:4,
fin:1,
syn:1,
rst:1,
psh:1,
ack:1,
urg:1,
ece:1,
cwr:1;
#elif defined(__BIG_ENDIAN_BITFIELD)
__u16 doff:4,
res1:4,
cwr:1,
ece:1,
urg:1,
ack:1,
psh:1,
rst:1,
syn:1,
fin:1;
#else
#error "Adjust your <asm/byteorder.h> defines"
#endif
__be16 window;
__sum16 check;
__be16 urg_ptr;
};


字节序详解:大小端与网络字节序的转换及避坑指南 在计算机底层的数据存储与网络传输中,多字节整数的排列顺序决定了数据能否被正确解析。这种排列规则被称为字节序,分为小端和大端两种模式,分别对应低位字节存放在低地址或高地址的存储习惯。理解字节序原理不仅有助于掌握内存布局,更是编写跨平台网络程序的基础。主机字节序由CPU架构决定,而网络字节序则统一采用大端约定,确保不同设备之间的通信一致。在实际工程中,通过htons、htonl等函数进行显式转换,可有效避免协议对接中的隐蔽错误。无论是嵌入式开发、协议调试,还是二进制数据处理,掌握字节序判断与转换方法都是提升代码 阅读详情

相关推荐

大小端字节序详解

正确区分大小端字节序,手把手带你做大小端面试题。

威威的博客 6544

字节序详细解读

概念来了!!!看概念肯定完犊子,接下来我们明确几个概念。。。什么是高字节?什么是低字节?在一个n进制的位中,最左边的位叫最高有效位,最右边的叫最低有效位。举个例子,1个int的整数123456789按照从右向左的方向,二进制中,0101是低字节,最左边的0000是高字节;十六进制中,15是低字节,07是高字节。再通俗一点解释就是:8421码的,8这端为高位,1这端为低位,相应的字节则分别称为高位字节和低位字节。补充:进制转换在内存中,多字节对象都是被存储为连续的字节序列。假设将int整型在内存中的起始地址(

打不倒的程序猿 9656

5.5_数据的存储和排列

计算机组成原理之数据的存储和排列

人生得意须尽欢 1139

字节序(Endian),大端(Big-Endian),小端(Little-Endian)

在各种计算机体系结构中,对于字节、字等的存储机制有所不同,因而引发了计算机通信领域中一个很重要的问题,即通信双方交流的信息单元(比特、字节、字、双字等等)应该以什么样的顺序进行传送。如果不达成一致的规则,通信双方将无法进行正确的编/译码从而导致通信失败。目前在各种体系的计算机中通常采用的字节存储机制主要有两种:big-edian和little-endian。  字节顺序 End

Chelin Tsien的专栏 877

本地部署大模型 vs 网页版大模型区别

fill:#333;color:#333;color:#333;fill:none;本地服务器/工作站硬件资源私有化部署GPU集群高速存储模型文件训练框架推理引擎。

Ds-Rag的博 1713

生信人的一天~HIFI数据+HIC数据组装基因组

HIFI+HIC数据组装基因组!

qq_43337286的博客 9530

字节与地址

int占4个字节,char占1个字节,每个字节占了1个地址,所以int a=10中的a就占了4个字节,将在4个连续的地址中存储,但是打印的时候只会显示第一个字节所在的地址。

2301_76614607的博客 555

Innovus快捷键大全:从入门到精通的效率提升指南

本文是Innovus快捷键从入门到精通的效率提升指南,旨在帮助芯片后端设计工程师通过掌握核心快捷键,将重复性鼠标操作转化为高效的肌肉记忆,从而显著提升版图设计、编辑和分析的工作流速度。文章系统讲解了视图导航、对象选择编辑、流程管理等关键快捷键组合,并提供了个性化配置与实战策略,助力工程师突破效率瓶颈,实现人机合一的流畅设计体验。

silver的专栏 797

Linux网络字节序详解:从理论到实践

本文详细介绍了Linux网络编程中的字节序问题。主要内容包括:字节序的两种类型(大端序和小端序)、常见处理器的字节序差异、网络字节序的概念及其重要性。重点讲解了Linux提供的字节序转换函数(htonl/ntohl等)及其应用场景,并通过IP协议头处理的实例演示了实际应用。文章还提供了调试技巧、现代开发中的处理方法以及性能优化建议。最后强调正确处理字节序是网络编程的基础,建议在不同平台测试代码并使用现代序列化框架减少手动处理。

软件科学-郝学胜 1641

【Cursor+Playwright-MCP 实现 AI 自主功能测试】含实例代码脚本+保姆级教程

本文档详细介绍了如何使用 Cursor(AI 编程助手)和 Playwright-MCP 库实现基于 GPT 模型的自动化功能测试。文档从环境搭建开始,逐步指导读者如何通过 Playwright 进行浏览器自动化,并利用 Playwright-MCP 集成 GPT 模型生成测试计划、执行测试步骤及生成测试报告。核心步骤包括安装依赖、配置 OpenAI API 密钥、编写代码实现 AI 驱动的测试流程,以及生成详细的测试报告。通过本文档,读者可以快速掌握从 0 到 1 实现 AI 自主功能测试的全流程。

Dreams°的博客 2894

Qt实现思维导图功能5『纵向分布模式』

思维导图纵向分布模式:模式一

浮生流年的博客 1062

网络字节序和主机字节序详解!!!

我们都知道,如今的通讯方式已经趋向与多样化,异构通信(计算机软件(操作系统) +    计算机硬件(内核架构,ARM,x86)不同)也已经很普遍了,如,手机和电脑中的qq进行通信,,, 同时,在计算机设计之初,对内存中数据的处理也有不同的方式,(低位数据存储在低位地址处或者高位数据存储在低位地址处),然而,在通信的过程中(ISO/OSI模型和TCP/IP四层模型中),数据被一步步封装(然

L未若的博客 3万+

ABAP CDS SELECT, parameters 全面解析:把参数化视图玩明白(含可运行示例)

这篇技术博客介绍了ABAP CDS中参数化视图的用法与实践。文章从业务需求出发,解释了参数化视图的必要性,并详细说明了语法规则、参数类型匹配、视图内部参数引用等关键点。重点展示了在JOIN和ASSOCIATION中传递参数的写法,提供了航线分析的完整业务案例和可运行代码示例。文章还总结了视图实体与DDIC视图的差异、会话变量使用技巧等实践要点,特别强调了JOIN中必须显式传参的语法要求。通过真实场景演示,帮助开发者掌握参数化CDS的高效应用。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 364

字节序详解:主机字节序到网络字节序

计算机处理的数据单位是字节,即8位二进制数,对于大于一字节的数据类型(如4字节的int),它们内存中占用着多个连续的字节。多个连续的字节是按照什么什么顺序排列在内存地址中的?这引出了字节序的概念。字节序(Byte Order)是多字节数据在内存中存储各字节的排列顺序。理解字节序有助于理解内存布局和跨平台数据传输,是深入计算机系统和网络与网络通信的第一步,go。

weixin_45467593的博客 1228

2024-12月js逆向案例-sensor-data之vmp字段之akamai_2/3.0-(下)

akamai2/3的vmp字段逆向分析

十一姐的博客 3147

软考中级-软件设计师 Python基础

软考中级-软件设计师 Python知识点整理

片言可决讼,半纸能缚龙 3643

网络字节序和主机字节序详解

我们都知道,如今的通讯方式已经趋向与多样化,异构通信(计算机软件(操作系统) + 计算机硬件(内核架构,ARM,x86)不同)也已经很普遍了,如,手机和电脑中的qq进行通信,,, 同时,在计算机设计之初,对内存中数据的处理也有不同的方式,(低位数据存储在低位地址处或者高位数据存储在低位地址处),然而,在通信的过程中(ISO/OSI模型和TCP/IP四层模型中),数据被一步步封装(然后加入信息首部),当传到目的段时,被一步步解封,然后获取数据 从上面我们可以看出,数据在传输的过程中,一定有一个标准化的过

Lee notes 1375

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

详解主机字节序和网络字节序(大小端),以及网络数据传输中如何处理字节序

图文结合,细致清晰地讲解如何正确理解网络字节序,以及网络传输中的多字节数据如何处理字节序问题,使得接收/发送端正确解析数据

道法自然 4410

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

字节序转换详解

在跨平台和网络编程中我们经常会提到网络字节序和主机字节序,如果没有正确对两者进行转换,从而导致两方产生了不同的解释,就会出现意想不到的bug。 目录 0x01 概念 0x02 分类 0x03 两种字节序之间的区别 0x01 概念 字节序,就是大于一个字节类型的数据在内存中的存放顺序。 注:网络字节序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统等无关,从而可以保证数...

无心的博客 5087

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

大小端字节序知识详解

计算机硬件有两种储存数据的方式:大端字节序(big endian)和小端字节序(little endian)。 举例: 数值0x2211使用两个字节储存:高位字节是0x22,低位字节是0x11。 大端字节序:高位字节在前,低位字节在后,这是人类读写数值的方法。 小端字节序:低位字节在前,高位字节在后,即以0x1122形式储存。 怎么去记才不会出错呢? 其实只需要记住小端是低位字节存低位数据,高位字节存高位数据。(称为:低低高高) 同理:0x1234...

lilang66的专栏 5646

90、字节序详解及Cpp判断方法

90、字节序详解及Cpp判断方法

m0_63008237的博客 433

字节序与比特序详解

[TOC]字节序的定义字节序就是说一个对象的多个字节在内存中如何排序存放,比如我们要想往一个地址a中写入一个整形数据0x12345678,那么最后在内存中是如何存放这四个字节的呢?  0x12这个字节值为最高有效字节,也就是整数值的最高位(在本文中0x12=0x12000000),0x78为最低有效字节。  这里就分为大端字节序和小端字节序  大端字节序:便是指最高有效字节落在低地址上的字节

godleading的专栏 9134

字节序Endian与字节序标记BOM详解

目录字节序字节序标记参考 字节序 字节序(Endian),就是字节顺序(Byte-Order),还叫端序或尾序(Endianness)。描述的是计算机对多字节数据存储和传输时字节的顺序。因为单字节的数据只需要读取一个字节,没有字节序说法。 字节序分为两种排列模式,分别是大端字节序和小端字节序。 大端(Big-endian):高位字节数据存放在内存低地址处,低位字节数据存放在内存高地址处。大端模式比较符合人类的阅读习惯,也这是人类读写数值的方式。 小端(Little-endian):高位字节数据存放在内存高

小龙狗的博客 8053
上一篇: 360极速浏览器之所以极速的另一可能原因——窗口
下一篇: Linux协议栈代码阅读笔记(三)报文接收
无忧老猪
博客等级 码龄18年 200粉丝 112原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值