I’m confused about unaligned memory accesses on ARM.

My understanding was that they’re not allowed — that is,

dereferencing a 32-bit value from a pointer that’s not four-byte aligned will crash.

I’ve run into such crashes before.

But right now I’ve got a situation where the Release build of an app crashes on an unaligned access,

but the Debug build doesn’t!

It’s the exact same place in the code — a CRC32 hash implementation —

and I’ve verified that an odd address is being dereferenced (as a uint32*).

(This is a 32-bit process running on an iPhone 5, by the way.)

The only difference is in the assembly code generated.

In the debug build it’s using ldr, while in the release build it’s using ldrd.

(Apparently the optimizer is smart enough to realize that the next line of code is loading the next 4 bytes after the pointer,

so it decides to combine both lines into a single instruction.)

So I’m guessing that ldr (a 32-bit load) allows unaligned access,

but ldrd (64-bit) doesn’t?

Is there any comprehensive, up-to-date documentation about this?

I’ve found an article from 2010* stating that unaligned accesses are supported but are slower because they trigger an OS trap (as on PPC);

but it doesn’t say anything about ldrd.

There’s a StackOverflow Q&A about a crash with ldrd**, where the answer states that "ldrd needs the address to be 8-byte aligned”.

But if that’s so, then I think the compiler optimization (-Ofast level) in my app was incorrect, because the value it’s dereferencing is a uint32_t*,

so there’s no expectation that it's 8-byte aligned.

I believe ARM requires 8-byte loads (ldrd, or doubles into the FPU, etc) require 8-byte alignment and will crash otherwise.

4-byte loads do not require alignment but will be slower if the pointer is not 4-byte aligned.

It will not crash though.

对于arm中的双字节或者4字节数据的访问,不能直接通过数据类型的强制转换来实现,必须通过单字节的方式:

使用单字节赋值,或者memcpy等函数,不过这样做的时候,首先要先确定数据是大端还是小端模式。

非对齐的数据访问操作

对于Load/Store操作,如果是非对齐的数据访问操作,系统定义了下面3种可能的结果.

执行的结果不可预知.

忽略字单元地址的低两位,即访问地址为(address _and 0xffffffc)的字单元;忽略半字单元地址的最低位的值,即访问地址位(address _and 0xffffffe)的半字单元.

忽略字单元地址值种的低两位的值;忽略半字单元地址的最低位的值.有存储体统实现这种”忽略”.也就是说,这时该地址值原封不动的送到存储系统.

当发生非对齐的数据访问时,到底采用上述3种处理方法种的哪一种,是有各指令指定的.

ARM 非对齐的数据访问操作的更多相关文章

  1. 在MyBatis中查询数据、涉及多参数的数据访问操作、插入数据时获取数据自增长的id、关联表查询操作、动态SQL、关于配置MyBatis映射没有代码提示的解决方案

    1. 单元测试 在单元测试中,每个测试方法都需要执行相同的前置代码和后置代码,则可以自定义2个方法,分别在这2个方法中执行前置代码和后置代码,并为这2个方法添加@Before和@After注解,然后, ...

  2. ARM非对齐访问和Alignment Fault

    1.指令对齐 A64指令必须word对齐.尝试在非对齐地址取值会触发PC alignment fault. 1.1.PC alignment checking PC(Program Counter)寄 ...

  3. ARM非对齐操作异常解决过程

    在测试MF固件时,发生一个非常诡异的异常,代码如下: CLR_DBG_Commands::Monitor_EraseMemory* cmd = (CLR_DBG_Commands::Monitor_E ...

  4. C++成员变量内存对齐问题,ndk下非对齐的内存访问导致BUS_ADRALN

    同样的代码,在vs下运行正常,在android ndk下却崩溃: signal 7(SIGBUS),code 1 (BUS_ADRALN),fault addr 0xe6b82793 Func(sho ...

  5. SharePoint 服务器端对象模型 之 使用LINQ进行数据访问操作(Part 2)

    (四)使用LINQ进行列表查询 在生成实体类之后,就可以利用LINQ的强大查询能力进行SharePoint列表数据的查询了.在传统SharePoint对象模型编程中,需要首先获取网站对象,再进行其他操 ...

  6. SharePoint服务器端对象模型 之 使用LINQ进行数据访问操作(Part 4)

    (六)高效合理的使用LINQ 1.DataContext中的两个属性 为了能够使用DataContext进行数据提交,在DataContext进行数据查询和操作的过程中,内部会进行数据状态的保持和追踪 ...

  7. 非对齐访问(unaligned accesses)

    从CPU角度看内存访问对齐 结构体成员非对齐访问所带来的思考 ARM体系中存储系统非对齐的存储访问操作 什么是cache line? cache line就是处理器从RAM load/store数据到 ...

  8. ARM字节对齐问题详解

    一.什么是字节对齐,为什么要对齐? 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问,这 ...

  9. Springboot数据访问,棒棒哒!

    Springboot对数据访问部分提供了非常强大的集成,支持mysql,oracle等传统数据库的同时,也支持Redis,MongoDB等非关系型数据库,极大的简化了DAO的代码,尤其是Spring ...

随机推荐

  1. 从字节码的角度看Java内部类与外部类的互相访问

    Java中non-static内部类为何可以访问外部类的变量?Java中外部类又为何可以访问内部类的private变量?这两个问题困扰过我一段时间,查了一些网上的答案,大多从“闭包”概念入手,理解起来 ...

  2. npm 更换阿里镜像

    使用NPM(Node.js包管理工具)安装依赖时速度特别慢,只需要使用–registry参数指定镜像服务器地址, npm install your-need-model --registry=http ...

  3. 日期控件-my97DatePicker用法

    网上资料,用法,只能选最近30天等等:http://jingyan.baidu.com/article/e6c8503c7244bae54f1a18c7.html

  4. Python 入门基础11 --函数基础4 迭代器、生成器、枚举类型

    今日目录: 1.迭代器 2.可迭代对象 3.迭代器对象 4.for循环迭代器 5.生成器 6.枚举对象 一.迭代器: 循环反馈的容器(集合类型) 每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的 ...

  5. 【API】NetUserEnum-获取系统所有账户名称

    1 说明 该NetUserEnum函数检索服务器上所有用户帐户的信息. 函数原型: NET_API_STATUS NetUserEnum( _In_ LPCWSTR servername, _In_ ...

  6. 如何生成能在没有安装opencv库及vs2010环境的电脑上运行的exe文件

    项目基本算法已经完成,甲方需要一个可以运行的demo.目前,程序能在自己的电脑上正常运行.移植到其他win7系统上,运行失败. 寻找各种解决办法,baidu找到两个办法: 1.使用静态链接的方法,这种 ...

  7. Android 7.0 新增功能和api

    Android 7.0 Nougat 为用户和开发者引入多种新功能.本文重点介绍面向开发者的新功能. 请务必查阅 Android 7.0 行为变更以了解平台变更可能影响您的应用的领域. 要详细了解 A ...

  8. 全键盘操作Windows

    计算机机用户在使用计算机的时候,是用键盘多一点?还是用鼠标多一点?如果是专业打字员,应该会说他使用键盘多一点,除此之外,多数人都会告诉你,他已经离不开鼠标了,没有鼠标,就不会操作电脑.   如果某一天 ...

  9. Python3.6安装OpenCV

    1.安装依赖 pip install --upgrade setuptools pip install numpy Matplotlib -i https://mirrors.aliyun.com/p ...

  10. List集合去除重复对象及equals()、hashCode()方法的作用

    原文:https://blog.csdn.net/freelander_j/article/details/52211010 在java中,要将一个集合中重复的对象除去,如果这个集合中的数据类型是基本 ...