当前位置:首页 > > strongerHuang
[导读]关注、 星标公众号,不错过精彩内容 素材来源:网络 编辑整理:strongerHuang 之前给大家分享过大小端的一些内容,阅读本文之前可以再次回顾一下: 你真的懂CPU大小端模式吗? 大小端格式由编译器还是CPU决定的? 一、回顾字节序 拿数据 0x01020304为例: 在


关注、 星标公众,不错过精彩内容

素材来源:网络

编辑整理:strongerHuang


之前给大家分享过大小端的一些内容,阅读本文之前可以再次回顾一下:

CPU大小端模式吗?" tab="innerlink" data-linktype="2" rel="nofollow">你真的懂CPU大小端模式吗?

大小端格式由编译器还是CPU决定的?


一、回顾字节序

拿数据 0x01020304为例:


在大端CPU中:数据将存储为0x01(address + 0),0x02(address + 1),0x03(address + 2),0x04(address + 3)。


在小端CPU中:数据将存储为0x04(address + 0),0x03(address + 1),0x02(address + 2),0x01(address + 3)。


如果你的程序使用简单的数据结构(例如“ int”和“ short”),则没有什么麻烦。但是,如果数据结构类似于以下示例,则可能会遇到问题。

union { unsigned int dat; unsigned char c[4]; }X;
void foo( ) { int t0; X.dat = 0x01020304; t0 = X.c[0]; ・・・}

在大端 CPU 中编译并执行此代码时, t0”的值为0x01。在小端CPU中, t0”的值为0x04。


那么问题来了:要想使存储顺序从大端,变为小端,怎么办呢?


方法其实有很多种,这里讲讲针对IAR的两种方法:

  • 使用__big_endian关键字。

  • 使用__REV, __REV16, __REVSH, RBIT函数。


二、使用__big_endian关键字

IAR中__big_endian关键字提供了一种方便的方式来将应用程序从big-endian移植到little-endian。


__big_endian关键字用于访问以big-endian字节顺序存储的变量,而与应用程序其余部分使用的字节顺序无关。在ARMv6或更高版本进行编译时,可以使用__big_endian关键字。


只需添加__big_endian关键字即可,如:

____big_endian union { unsigned int dat; unsigned char c[4]; }X;
void foo( ) {int t0;X.dat = 0x01020304;t0 = X.c[0];・・・}

修改后的代码在低位字节CPU中编译和执行,变量“ t0”为0x01。


注意:此关键字不能用于指针。同样,此属性不能在数组上使用。

同时,关键字__big_endian插入REV指令以交换字节数据,REV指令的插入会影响代码大小和执行时间。


关键字具有限制,不能应用于复杂的数据结构,比如以下代码会生成错误

__big_endianunion { unsigned long dat; unsigned char c[4]; struct { unsigned long a0: 1; unsigned long a1: 1; unsigned long a2: 2; unsigned long a3: 4; unsigned long a4: 8; unsigned long a5: 16; }s;} f1_dat2;


三、使用__REV, __REV16, __REVSH, RBIT函数

大端和小端之间的字节顺序差异只是顺序,因此我们需要做的是更改字节顺序,我们再次以变量0x01020304为例:


我们可以通过代码实现交换功能,比如:

typedef unsigned long uint32_t;uint32_t bswap_32(uint32_t x) {  uint32_t t = x;  uint32_t s;  s = ( (((uint32_t)(t) & (uint32_t)0x000000ffUL) << 24) |    (((uint32_t)(t) & (uint32_t)0x0000ff00UL) << 8) |      (((uint32_t)(t) & (uint32_t)0x00ff0000UL) >> 8) |  (((uint32_t)(t) & (uint32_t)0xff000000UL) >> 24) ); return s; }

通过这种方式实现,将导致消耗更多时间和代码大小。

在C代码中,我们通常编写内联汇编代码实现交换。IAR有种内部函数可以实现该功能。

比如下面交换功能:


代码如下:
#include <intrinsics.h>void x1( void ) {s2 = __REV(s1);s3 = __REV16(s1);s4 = __REVSH(s1);}

当然,具体的使用以及细节内容,需要看查看官方说明。


                              
免责声明: 本文素材来源网络,版权归原作者所有。如涉及作品版权问题,请与我联系删除。
推荐阅读:
IAR进军Linux,支持在Linux搭建编译环境
Linux 为何会流行?它和普通的RTOS有何区别?
Windows Terminal 1.0 和 Linux 版有啥区别

关注 微信公众号『strongerHuang』,后台回复“1024”查看更多内容,回复“加群”按规则加入技术交流群。


长按前往图中包含的公众号关注

免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
换一批
延伸阅读

在数字电路的庞大体系中,加法器是最基础却又至关重要的运算单元。从简单的计算器到复杂的CPU,加法器如同数字世界的“基石”,支撑着几乎所有的算术运算。无论是日常生活中购物时的金额计算,还是航天领域中精密的轨道运算,背后都离...

关键字: 加法器 CPU

在多线程编程的世界里,死锁就像潜伏在代码中的幽灵,时不时就会出来作祟。它让线程们陷入互相等待的僵局,程序看似运行却毫无进展,CPU使用率骤降,排查起来更是让人头疼不已。GDB(GNU调试器)作为Linux平台下的调试利器...

关键字: GDB CPU

在Linux操作系统中,进程管理是核心功能之一,而进程调度与切换则是保障系统高效、稳定运行的关键机制。它们决定了CPU资源如何分配给各个进程,直接影响着系统的响应速度、吞吐量和公平性。

关键字: Linux CPU

在数字化浪潮席卷全球的当下,物联网、嵌入式系统与单片机这三个技术名词频繁出现在科技报道、产业论坛以及校园课堂中。它们看似独立,实则紧密相连,共同构成了推动智能时代发展的核心技术链条。从智能家居里自动调节温度的空调,到工业...

关键字: 单片机 CPU

随着端侧AI和高性能计算需求的快速增长,处理器产业的分工模式正在发生变化。近期,Arm 已发布其自研AI芯片,这一动向也让产业对IP模式的开放性与生态中立性产生了更多关注。

关键字: SoC RISC-V CPU

在嵌入式系统发展历程中,51单片机与STM32单片机无疑是两个具有里程碑意义的产品。诞生于上世纪80年代的51单片机,凭借简单易用、成本低廉的特性,成为无数开发者的入门导师,推动了嵌入式技术的普及;而2003年问世的ST...

关键字: 单片机 CPU

4月2日,在海光信息2026年春季技术沟通会上,海光信息正式公开基于“内生安全”理念的一大批新技术、新成果,并首发海光DCU软件栈年度版本,为业界清晰地描绘出海光双芯产品(CPU、DCU)推动国产万亿大模型研发、加速各行...

关键字: 大模型 CPU DCU

北京2026年4月2日 /美通社/ -- 3月31日,2026年度中国IC设计成就奖在上海举办的国际集成电路展览会暨研讨会期间隆重颁布。作为兆芯面向人工智能、云计算、数据中心、高密度存储等前沿技术与核心应用打造的新一代自...

关键字: IC设计 处理器 CPU 通用处理器

由台达集团于2026年3月29日通过美通社发布新闻稿《集装箱式SST直流移动智算中心发布》中,第3张有误,已进行替换。特此更正,更新后的全文及图片如下: 集装箱式SST直流移动智算中心发布 台达、汉腾科技、龙芯中科携...

关键字: 移动 ST 固态变压器 CPU

面对AI Agent与Physical AI的浪潮,单纯依靠增加GPU或NPU的补丁式方案已难以为继,CPU架构必须进行面向AI的底层重塑。 阿里达摩院发布的玄铁C950旗舰处理器,不仅刷新了单核性能纪录,更通过原生A...

关键字: 玄铁C950 CPU AI 物理AI RISC-V
关闭