大端小端模式判断以及数据转换

简介

在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为 8bit。但是在C语言中除了8bit的char之外,还有16bit的short型,32bit的long型(要看具体的编译器),另外,对于位数大于 8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。考虑一个short整数0xAF32(0x32是低位,0xAF是高位),把它赋值给一个short变量,那么它在内存中的存储可能有如下两种情况:

  • 大端字节(Big-endian):较高的有效字节存放在较低的存储器地址,较低的有效字节存放在较高的存储器地址。
  • 小端字节(Big-endian):字数据的高字节存储在高地址中,而字数据的低字节则存放在低地址中。
    地址    0x2000  0x2001+-+-+-+-+-+-+-+-+
    大端存储 |  0xAF |  0x32 |+-+-+-+-+-+-+-+-+
    小端存储 |  0x32 |  0xAF |+-+-+-+-+-+-+-+-+
    

C函数判断大小端

判断计算机的存储方式:

// 是小端模式则返回1,否则返回0
int is_little_endian()
{union w{int x ;char y ;}c ;c.x = 1;return (c.y==1);
}

大端模式和小端模式转换

#include<stdio.h>typedef unsigned int uint_32 ;
typedef unsigned short uint_16 ;#define BSWAP_16(x) \(uint_16)((((uint_16)(x) & 0x00ff) << 8) | \(((uint_16)(x) & 0xff00) >> 8) \)
#define BSWAP_32(x) \(uint_32)((((uint_32)(x) & 0xff000000) >> 24) | \(((uint_32)(x) & 0x00ff0000) >> 8) | \(((uint_32)(x) & 0x0000ff00) << 8) | \(((uint_32)(x) & 0x000000ff) << 24) \)uint_16 bswap_16(uint_16 x)
{return (((uint_16)(x) & 0x00ff) << 8) | \(((uint_16)(x) & 0xff00) >> 8) ;
}
uint_32 bswap_32(uint_32 x)
{return (((uint_32)(x) & 0xff000000) >> 24) | \(((uint_32)(x) & 0x00ff0000) >> 8) | \(((uint_32)(x) & 0x0000ff00) << 8) | \(((uint_32)(x) & 0x000000ff) << 24) ;
}
int main(int argc,char *argv[])
{printf("------------带参宏-------------\n");printf("%#x\n",BSWAP_32(0x12345678));printf("%#x\n",BSWAP_16(0x1234)) ;printf("------------函数调用-----------\n");printf("%#x\n",bswap_32(0x12345678));printf("%#x\n",bswap_16(0x1234)) ;return 0 ;
}

标准库是如何识别大小端模式的

在系统头文件/usr/include/bits/endian.h中定义表示大小端的宏变量,如

# cat /usr/include/bits/endian.h 
/* i386/x86_64 are little-endian.  */#ifndef _ENDIAN_H
# error "Never use <bits/endian.h> directly; include <endian.h> instead."
#endif#define __BYTE_ORDER __LITTLE_ENDIAN

应用可以参考/usr/include/netinet/tcp.h/中结构体的定义,如

struct tcphdr{u_int16_t source;u_int16_t dest;u_int32_t seq;u_int32_t ack_seq;
#if __BYTE_ORDER == __LITTLE_ENDIANu_int16_t res1:4;u_int16_t doff:4;u_int16_t fin:1;u_int16_t syn:1;u_int16_t rst:1;u_int16_t psh:1;u_int16_t ack:1;u_int16_t urg:1;u_int16_t res2:2;
#elif __BYTE_ORDER == __BIG_ENDIANu_int16_t doff:4;u_int16_t res1:4;u_int16_t res2:2;u_int16_t urg:1;u_int16_t ack:1;u_int16_t psh:1;u_int16_t rst:1;u_int16_t syn:1;u_int16_t fin:1;
#else
#error "Adjust your <bits/endian.h> defines"
#endifu_int16_t window;u_int16_t check;u_int16_t urg_ptr;
};

两种模式的使用现状

Intel的80x86系列芯片是唯一还在坚持使用小端的芯片,ARM芯片默认采用小端,但可以切换为大端;而MIPS等芯片要么采用全部大端的方式储存,要么提供选项支持大端——可以在大小端之间切换。另外,对于大小端的处理也和编译器的实现有关,在C语言中,默认是小端(但在一些对于单片机的实现中却是基于大端,比如Keil 51C),Java是平台无关的,默认是大端。在网络上传输数据普遍采用的都是大端。

#include <stdio.h>
struct ST{short val1;short val2;
};
union U{int val;struct ST st;
};int main(void)
{int a = 0;union U u1, u2;a = 0x12345678;u1.val = a;printf("u1.val is 0x%x\n", u1.val);printf("val1 is 0x%x\n", u1.st.val1);printf("val2 is 0x%x\n", u1.st.val2);printf("after first convert is: 0x%x\n", htonl(u1.val));u2.st.val2 = htons(u1.st.val1);u2.st.val1 = htons(u1.st.val2);printf("after second convert is: 0x%x\n", u2.val);return 0;
}

shell命令判断大小端模式

  • dpkg-architecture命令
    $ dpkg-architecture 
    DEB_BUILD_ARCH=arm64
    DEB_BUILD_ARCH_ABI=base
    DEB_BUILD_ARCH_BITS=64
    DEB_BUILD_ARCH_CPU=arm64
    DEB_BUILD_ARCH_ENDIAN=little
    DEB_BUILD_ARCH_LIBC=gnu
    DEB_BUILD_ARCH_OS=linux
    DEB_BUILD_GNU_CPU=aarch64
    DEB_BUILD_GNU_SYSTEM=linux-gnu
    DEB_BUILD_GNU_TYPE=aarch64-linux-gnu
    DEB_BUILD_MULTIARCH=aarch64-linux-gnu
    DEB_HOST_ARCH=arm64
    DEB_HOST_ARCH_ABI=base
    DEB_HOST_ARCH_BITS=64
    DEB_HOST_ARCH_CPU=arm64
    DEB_HOST_ARCH_ENDIAN=little
    DEB_HOST_ARCH_LIBC=gnu
    DEB_HOST_ARCH_OS=linux
    DEB_HOST_GNU_CPU=aarch64
    DEB_HOST_GNU_SYSTEM=linux-gnu
    DEB_HOST_GNU_TYPE=aarch64-linux-gnu
    DEB_HOST_MULTIARCH=aarch64-linux-gnu
    DEB_TARGET_ARCH=arm64
    DEB_TARGET_ARCH_ABI=base
    DEB_TARGET_ARCH_BITS=64
    DEB_TARGET_ARCH_CPU=arm64
    DEB_TARGET_ARCH_ENDIAN=little
    DEB_TARGET_ARCH_LIBC=gnu
    DEB_TARGET_ARCH_OS=linux
    DEB_TARGET_GNU_CPU=aarch64
    DEB_TARGET_GNU_SYSTEM=linux-gnu
    DEB_TARGET_GNU_TYPE=aarch64-linux-gnu
    DEB_TARGET_MULTIARCH=aarch64-linux-gnu
    
  • lscpu命令
    $ lscpu
    Architecture:        aarch64
    Byte Order:          Little Endian
    CPU(s):              4
    On-line CPU(s) list: 0-3
    Thread(s) per core:  1
    Core(s) per socket:  4
    Socket(s):           1
    Vendor ID:           ARM
    Model:               4
    Model name:          Cortex-A53
    Stepping:            r0p4
    CPU max MHz:         1296.0000
    CPU min MHz:         408.0000
    BogoMIPS:            48.00
    L1d cache:           unknown size
    L1i cache:           unknown size
    L2 cache:            unknown size
    Flags:               fp asimd evtstrm aes pmull sha1 sha2 crc32 cpuid
    

延伸阅读:

准确详解:C/C++ float、double数据类型的表示范围及精度

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/508629.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MSYS2下搭建Qt开发环境

最近随意浏览了一下俺们大省会城市的招聘信息&#xff0c;发现C招聘中涉及Qt经验的要求有不少&#xff0c;为了牛奶和面包&#xff0c;决心深入一下Qt开发。本篇文章由此而出。 Qt 关于Qt的人生经历在这不在累赘&#xff0c;资料随处可得&#xff0c;这里只记录干货。 环境搭…

CentOS7开发环境搭建(1)

文章目录BIOS开启VT支持U盘安装系统(2019-03-11)CentOS DNS配置CentOS网络配置配置静态IP克隆虚拟机网卡名称变更 CentOS6.5时间配置安装VMWare-tools用户管理 (2019-03-15 7.6.1810)给一般账号 root 权限Samba服务配置安装必备软件获取本机公网ipyum源和第三方库源管理配置本地…

ACM 欧拉公式

给出一个数X&#xff0c;求小于X的与X互质的数的个数&#xff0c;使用欧拉公式。 如果x1*x2*...*xnX,则个数nX*(1-1/x1)*(1-/x2)*... 使用这个的题目&#xff0c;超典型 相遇周期(HDOJ)

HDU 1495 非常可乐(BFS)

思路 最难在于想到这道题是BFS&#xff0c;想到之后只有六种情况就很好理解了。 代码 #include<stdio.h> #include<string.h> #include<math.h> #include<queue> using namespace std; int a,b,s; struct shui {int count;int ha,hb,hs; }t,t1; int m…

NBU计算机专业期末考试记录

考试科目&#xff1a;操作系统 软件工程 数据库 计算机网络 JAVA高级应用 汇编 计算机算法设计 操作系统&#xff1a;题目比较简单&#xff0c;这学期的大题有写读写互斥的代码、求平均磁道数、银行家算法、页面调度算法的缺页次数计算。期中考试有参考价值&#xff0c;要看懂…

蚁群算法的若干记录

1、蚁群算法的特点&#xff1a; ① 结合了分布式算法、正反馈机制、贪婪式搜索的算法&#xff1a;正反馈可以快速发现较优解、分布式算法避免早熟收敛、贪婪式搜索有助于早期找出可解决方案&#xff1b; ② 蚁群算法具有很强的并行性&#xff1b; ③ 个体之间通过信息素合作…

蚁群算法之二

1、蚂蚁系统模型的建立 给定G(V,A)&#xff0c;其中V为定点集&#xff0c;A为各顶点互相连接组成的边集,已知各顶点之间的连接距离&#xff0c;要求确定一条长度最短的回路&#xff0c;仅遍历一次所有顶点的回路。引入记号&#xff1a; m&#xff1a;蚁群中蚂蚁的数量&#x…

ns2相关学习——tcl脚本编写(1)

新建一个仿真实例&#xff1a; set ns [new Simulator]为了让nam文件和trace文件有地方可以依托&#xff0c;我们要打开.nam文件进行写入&#xff0c;并且使用句柄nf set nf [open out.nam w] $ns namtrace-all $nf设置拓扑图 1、设置节点的脚本语言&#xff1a;建了两个节点&…

ns2相关学习——TCL脚本编写(2)

下面来学习更加复杂一点的TCL脚本的编写 简述&#xff1a;建立有4个节点的拓扑&#xff0c;其中一个节点作为路由器&#xff0c;用来将两个节点发出的数据包转发到第四个节点上面。 在这里将解释将两个节点的数据流区分开来的方法&#xff0c;展示如何去检测一个队列是否是满…

ns2相关学习——TCL脚本编写(3)

在这里我们将学习动态网络的建立 1、建立拓扑 当节点很多的时候&#xff0c;我们可以使用循环的方式来建立拓扑。 for {set i 0} {$i < 7} {incr i} {set n($i) [$ns node] }这里的数组不需要事先声明。 2、建立链接 这里我们要把7个节点链成一个环儿&#xff0c;同样使用…

NS2相关学习——完成一个新的协议(1)

接下来要进入对我来说老大难的环节了&#xff0c;从表面的TCL慢慢进入到后端的C&#xff0c;一起加油学习吧~ 在本节学习中&#xff0c;将给出一个在ns中实现新的协议的例子。但是可以想见的是&#xff0c;如果由我们自己来完成这个工作&#xff0c;势必要对NS2十分的熟悉并且要…

NS2相关学习——完成一个新协议(2)

在上节中&#xff0c;我们把教程要求的3.1-3.3过了一遍&#xff0c;这一次回到正途上来。看看到底是怎么完成一个新的协议的。 本节中的代码实现了一些简单的“ping”协议&#xff08;灵感来自“ns注释和文档”&#xff08;现在更名为ns手册&#xff09;的第9.6章中的“ping请…

NS2相关学习——完成一个新协议(3)

在前面已经基本学习了怎么完成一个新协议&#xff08;一个神奇的ping协议&#xff0c;然鹅还是有点懵。。。&#xff09; 接下来继续学习相关知识 接着上一部分从1开始 1、必要的修改 如果想要添加添加新的代理程序&#xff0c;就需要修改NS源文件中的内容&#xff0c;特别…

NS2相关学习——创建Xgraph的输出文件

经过前面学习代码的编写&#xff0c;这一部分&#xff0c;我们要学会如何进行分析&#xff0c;一个很直观的方式就是将结果图形化表示出来。 ns-allinone包的一部分是“xgraph”&#xff0c;一个绘图程序&#xff0c;可用于创建模拟结果的图形表示。 在本节中&#xff0c;将向…

NS2相关学习——在ns中模拟无线场景

之前学习的都是有线场景下的NS2相关应用&#xff0c;现在开始&#xff0c;终于要学习无线啦&#xff01;无线是我研究的重点&#xff0c;要好好学习呀&#xff01;在本节中&#xff0c;我们将学习使用ns中提供的移动无线仿真模型。 该部分由两部分组成。 在第一小节中&#xff…

An Energy-Efficient Ant-Based Routing Algorithm for Wireless Sensor Networks (无线传感网中一种基于蚁群算法的能量有效路由)

牙说&#xff1a;这篇论文是研究蚁群算法在能量有效路由协议的过程中必读的一篇文章&#xff0c;原是全英文&#xff0c;在这里按照自己的理解大致翻译成中文&#xff0c;好好学习&#xff0c;与君共勉。 论文题目&#xff1a;An Energy-Efficient Ant-Based Routing Algorith…

活在幻梦中的你我

其实仔细想想,人类和地球上的其它物种有什么不同呢?可能仅有的不同是,人类会去相信那本来并不存在的事情. 并且会为了那种虚幻的东西为止拼搏、努力。比如科技的发展&#xff0c;不就是人类在实现自己想象中的事物么&#xff0c;飞机、轮船、家电、计算机等等&#xff0c;无一…

An Energy-Efficient Ant-Based Routing Algorithm for Wireless Sensor Networks (无线传感网中基于蚁群算法的能量有效路由)2

牙说&#xff1a;接着上一篇继续写。论文标题&#xff1a;An Energy-Efficient Ant-Based Routing Algorithm forWireless Sensor Networks作者&#xff1a;Tiago Camilo, Carlos Carreto, Jorge S Silva, Fernando Boavida正文&#xff1a; 2、相关工作可以考虑无线传感器网络…

NS2仿真分析无线网络的攻击防御(1)

这个学期有个选题是NS2仿真分析无线网络的攻击防御&#xff0c;比较有意思的样子&#xff0c;现在来慢慢学一下这个是什么东西。 首先&#xff0c;还是一篇文章&#xff08;老长老长了&#xff09;&#xff0c;还是全英文的&#xff0c;还是先来分析一下它到底在说什么&#x…

NS2仿真分析无线网络的攻击防御(2)

牙说&#xff1a;继续上一篇博文进行翻译。 4. NS和我们的工作 我们试图评估黑洞攻击在无线Ad-hoc网络中的影响。 为了实现这一点&#xff0c;我们已经使用NS 网络模拟 [14]程序模拟了一个含有黑洞节点的无线自组网络场景。为了模拟无线自组织网络中的黑洞节点&#xff0c;我…