ARM平台的字节对齐问题

发布者:快乐的舞蹈最新更新时间:2016-07-01 来源: eefocus关键字:ARM平台  字节对齐 手机看文章 扫描二维码
随时随地手机看文章
ARM流行已久,做嵌入式开发的不知道ARM不大可能。鉴于其所具备的较低功耗下的较高性能,也就成了大多数嵌入式设备的首选

不过对于刚上手的人来说,有可能会遇到一些稀奇古怪的问题。毕竟大部分人都习惯了IA-32下的程序设计,虽然两者都是32位的
构完全不同,于是也导致了一些隐含的问题。这里想描述一下一个有点蛊惑的问题,即在ARM上访问非对齐地址内容,会出现所
问题。
ARM内存访问的对齐问题
按照ARM文档上的描述,其访问规则如下:
1. 一次访问4字节内容,该内容的起始地址必须是4字节对齐的位置上;
2. 一次访问2字节内容,该内容的起始地址必须是2字节对齐的位置上;
(单字节的没有这个问题,就不用考虑啦。 )
好,既然规则如此,那应该遵守。不过么,不安分的人往往喜欢破坏规则,喜欢看看不遵守规则会有什么结果;另外么,即便遵
免考虑不周,犯个错也是正常现象。好,那么让我们来看看犯错的结果吧。例如下面的代码:
char buff[8] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xab, 0xbc, 0xcd};
int v32, *p32;
short v16, *p16;
p32 = (int*)&( buff[1] ); //unalignment
p16 = (short*)&( buff[1] ); //unalignment
v32 = *p32; //what’s the result?
v16 = *p16; //what’s the result?
如果上面这段代码在IA-32上运行,那么结果应该如下:
v32 = 0x9a785634
v16 = 0x5634
即便非对齐地址上访问,IA-32也就是牺牲一点性能,但是结果保证是正确的。恩,这也是我们所期望的……
可是…… 换到ARM上呢?我们来看看在ADS1.2编译后,执行的结果如下:

v32 = 0x12785634
v16 = 0x1234
这个结果有点奇怪了吧。照理说指向0x34,那么如果是Big-Endian的话,v32应该是0x3456789a,如果是Little-Endian的话,就是前面
可现在的结果呢?两者都不是,莫名地把更低地址的0x12给凑进来了…… 而如果看看编译生成的汇编code的话,这两个赋值很
ldrsh指令,指令没有问题,分别用于读取32位和16位数据,都是最基本的指令。嗯,嗯,这就是我们所要描述的访问非对齐地址的
问题的缘由(个人猜测,非官方资料……)
个人感觉呢,这是ARM体系架构实现的问题,或者说这本来就是By Design的。这样做简化了处理器的实现,IA-32实现的时候肯定
齐进行判断,然后转换为相应的操作 ,而ARM呢?没有做这个事情,默认认为大家都按照规矩办事,你要是胆敢破坏,俺就给你
那有没有办法解决呢?
这个问题其实ARM自己也知道,所以呢,它在编译器里面,已经添加了部分支持。不过有人会问,那上面那个情况呢?为什么结
有添加什么支持嘛……
嗯,其实ARM是做了一定的努力的,只是这个情况它没办法解决…… 它做的事情就是:在编译器能够的得知的情况下,尽量保证访问
话有点笼统,那么把具体情况一个个来看看吧。
编译器的努力(1)—— 所有局部/全局/静态等变量都放在4字节对齐的地址上
其实这个努力很常见,由于在32位平台上,一次访问4字节是效率最高的,所以大多数32平台的编译器都如此处理,ARM的ADS也不例外
编译器的努力(2)—— 填充、填充、再填充
这个事情么,其实也是常见的。各类编译器上,对于某些结构定义中会产生不对齐的情况,自动填充,以提高访问效率(例如IA
会加1个周期的)。而ARM的编译器也一样操作,不过感觉这里不单单是为了提高效率,也能够顺带解决这个不对齐的问题。
编译器的努力(3)—— 产生特殊代码
嗯,这个就是关键了,也是ARM编译器的与众不同之处。先来看一段代码:
__packed typedef struct _test
{
char a;
short c;
int d;
} test;
char buff[8] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xab, 0xbc, 0xcd};
test *p = (test *)buff;
v32 = p->d; //这里的v32借用上面的定义;
貌似多了个限定为__packed的struct,以此来造成不对齐的状况,看不出多大区别嘛。可是运行一下的话,就会发现这里的结果是正
ADS生成的汇编代码吧。
v32 = q->d;
[0xe2890003] add r0,r9,#3
[0xeb000088] bl __rt_uread4
[0xe1a05000] mov r5,r0

看到这里的那条"bl __rt_uread4"的指令了吧。对ARM指令有一定了解的都知道bl其实就是一个函数调用。所以,这里的代
自己提供的__rt_uread4函数,该函数完成的操作就是读取四个字节。ADS提供了类似的一系列函数,针对signed/unsigned,以及
写入操作。
估计看到这里,大家会问,如果没有__packed限定符呢?猜对了,没有__packed限定符,那么编译器会对上面的情况pending,
所在的位置是4字节对齐的(编译期信息,而非实际运行期信息)。所以就回到类似最初的例子了。
那么,还有一种情况,就是在有__packed的情况下,而struct里的字段都是符合对齐要求的,那么生成的代码会是怎么样的呢?
看,和上面的这段汇编代码,唯一的区别就是第一条指令把#3改成了#4,而后面仍旧调用__rt_uread4函数。嗯,这样结论就出
编译器会在使用__packed的情况下,自动对其中的4字节/2字节访问添加特殊代码,以保证其结果的正确。
好了,这个关于这个问题描述得差不多了,可能的话,尽量倚赖编译器的这些功能,而对于编译器无能为力的部分,就要靠万分小心了
p.s. 其实这里有很多事情可以来尽量预防此类问题,比如嵌入式项目往往喜欢自己管理内存分配,那么自己写的内存分配函数
字节对齐位置上的……

关键字:ARM平台  字节对齐 引用地址:ARM平台的字节对齐问题

上一篇:arm 下C编程的非对齐访问
下一篇:ARM平台的地址对齐问题

推荐阅读最新更新时间:2024-03-16 14:59

基于ARM CPU 的实时控制系统开发平台
1 前言 国内控制系统开发大多是几个人以小组的形式根据不同的项目组织在一起,由于缺乏一个稳定工作的硬件基础,整个开发工作的重点大都放在调试硬件故障。所有项目的开发几乎全部使用汇编语言,严重影响了程序的可读性和可移植性,更换不同的处理器就意味着一切从头开始,就连使用相同处理器的不同项目组之间的程序重用也很困难。而对于嵌入式应用系统应着重解决的实际问题往往无暇顾及,非常不利于我国嵌入式应用水平的提高;其次,测控系统通讯接口种类比较少, 多为传统的RS-232、RS-485接口,数据交换速度慢,已经不能满足日益增长的数据传输需求;再次,传统的8/16位单片机已经越来越不能适应日渐复杂的应用需求,友好的交互界面、网络互连功能、智能化的软件
[单片机]
基于ARM的多人对战游戏平台
  游戏不仅能开发人的智力,使人头脑反应灵敏,还能满足人的精神需求(如冒险、创造力、情感等),极具娱乐性和趣味性,深受人们的喜爱。随着消费类电子产业的蓬勃发展,越来越多的嵌入式电子产品走进了千家万户,催生出了诸如GBA(Game Boy Advance)、PSP(Play-Station Portabk)以及最近才在我国上市的iPad等一大批专业的并且销量惊人的明星级移动娱乐游戏设备。   然而上述游戏平台通常造价昂贵,且不具有开放性。例如备受推崇的PSP,开发授权问题和昂贵的专用开发套件(软硬件)使得PSP游戏的开发门槛很高。这在很大程度上限制了这些游戏平台的普及。如果利用通用的处理器和常用的嵌入式操作系统(如WinCE、Li
[单片机]
基于<font color='red'>ARM</font>的多人对战游戏<font color='red'>平台</font>
cortex-m3 栈的8字节对齐
一、什么是栈对齐? 栈的字节对齐,实际是指栈顶指针须是某字节的整数倍。因此下边对系统栈与MSP,任务栈与PSP,栈对齐与SP对齐 这三对概念不做区分。另外下文提到编译器的时候,实际上是对编译器汇编器连接器的统称。 之前对栈的8字节对齐理解的不透,就在网上查了好多有关栈字节对齐、还有一些ARM对齐伪指令的资料信息,又做了一些实验,把这些零碎的信息拼接在一起,总觉得理解透这个问题的话得长篇大论了。结果昨天看了AAPCS手册、然后查到了没有使用PRESERVE8伪指令出现错误的实例,突然觉得长篇大论不存在了,半篇小论这问题就能理顺了。 二、AAPCS栈使用规约 在ARM上编程,但凡涉及到调用,就需要遵循一套规约AAPCS:《Proce
[单片机]
Arm中国自主研发“周易”平台,让AI无处不在
随着新技术的成熟,新型的先进应用将来自5G、人工智能(AI)和物联网(IoT)的融合,这种融合将创造出一个智能互联的全新未来,对所有个人、行业、社会和经济产生积极影响。Arm预计到2035年将有1万亿的物联网设备,在这些设备上实现本地人工智能,是人工智能应用的必然趋势。而要做到这一点,必须进一步降低人工智能的算力成本。 为此,Arm中国自主研发了“周易”平台这样一个适配性强、开放通用的人工智能平台,其主要包括软件框架Tengine和全新的硬件处理器——人工智能处理单元(AIPU),其中Tengine软件框架针对边缘设备的推理做了深度优化和实现。周易平台也支持Arm CPU、Mali GPU以及第三方硬件,专注于边缘推理,能够提
[物联网]
<font color='red'>Arm</font>中国自主研发“周易”<font color='red'>平台</font>,让AI无处不在
赛普拉斯推出支持Arm平台安全架构Trusted Firmware-M的参考实例
赛普拉斯半导体公司近日宣布,推出基于PSoC®6 MCU的支持Arm®平台安全架构(PSA)Trusted Firmware-M的参考实例,是符合PSA标准的最高级别保护能力的解决方案。通过利用PSA全套威胁模型、安全分析、硬件和固件架构规范以及Trusted Firmware-M设计参考,IoT设计人员可以快速、轻松地使用PSoC 6 MCU实现安全设计。 Arm物联网设备IP业务部副总裁兼总经理Paul Williamson表示:“互联设备正在快速发展,为了真正实现这些技术所带来的效益,安全性不可忽视。在广大IoT应用中实现安全的MCU开发是业界的共同责任,而赛普拉斯的PSoC 6 MCU将进一步把PSA的优势扩展到整个生
[半导体设计/制造]
ARM嵌入式平台的VGA接口设计
大多数嵌入式产品的显示终端都选择LCD,但在某些需要大屏幕显示的应用中,工业级LCD的价格比较昂贵,且现有的大屏幕显示器(包括CRT显示器和LCD显示器)一般都采用统一的15针VGA显示接口。三星公司ARM9芯片S3C2410以其强大的功能和高性价比在目前嵌入式产品中得到广泛的应用。笔者在开发基于ARM嵌入式平台的血液流变测试仪的过程中,成功地利用高性能视频D/A转换芯片ADV7120,将S3C2410自带的LCD扫描式接口转换为VGA接口,使之能够驱动VGA接口的显示器。 1 VGA接口介绍 近年来,业界制定出了众多数字化的显示接口协议,较为典型的是DVI(Digital Visual Interface)。由于数字接口的标
[工业控制]
MSP430之共用体中结构体字节对齐问题
先上代码: 我所用的平台的字节对齐默认是2字节,下面////////之间的变量定义为7个字节,为了保证2字节对齐,Power变量就会自动扩展一个字节,但是变量类型又是一个字节,所以发生了字节偏移的情况。 typedef union _PARARW{ struct{ UINT8 Name ; /////////////////////////////// UINT8 Read; UINT8 Start; UINT8 Stop; UINT8 Alarm; UINT8 Unit; // UINT8 Nothing;//字节对齐填充 UINT8 Display; UINT8 Power; ///
[单片机]
MSP430之共用体中结构体<font color='red'>字节</font><font color='red'>对齐</font>问题
基于ARM7和VC平台的高分辨率红外触摸屏设计
    触摸屏是结合显示器使用的一种透明的绝对定位系统,透明和优良的定位原理是它的技术特征。目前应用在各场合的触摸屏主要有四种:电阻式触摸屏、电容式触摸屏、表面声波触摸屏和红外触摸屏。其中红外触摸屏的视觉效果和定位原理都优于其它触摸屏技术,而且不受电流、电压和静电干扰,可以适宜恶劣的环境条件。但是,与其它三种触摸屏相比,红外触摸屏也存在分辨率低的问题,这一点严重影响了红外触摸屏的实际应用。   为此,本文采用ARM7和VC提出了一种高分辨率的红外触摸屏的实现方案。该方法通过ARM7对接收管和发射管的控制,来实时采集与发射管一一对应的接收管的光通量,然后计算鼠标位置,最后通过VC编程来实现在Windows下的鼠标驱动。   1硬
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved