ARM 非對齊的資料訪問操作

來源:互聯網
上載者:User

標籤:

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 非對齊的資料訪問操作

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.