c - 如何强制 arm gcc 编译器不对未对齐的内存使用 32 位访问
问题描述
我在一个无法处理未对齐地址上的 32 位访问的内存上工作。对于未对齐的地址,内存支持 8 位级访问。
在我的代码中有一个 memcpy,当我将未对齐的地址传递给 memcpy 时,芯片卡住了。经过深入研究,我发现生成的 memcpy 汇编代码正在对地址进行 32 位访问,无论给定地址是否与 32 位对齐。当我将优化级别降低到 O(2) 时,编译器会生成始终执行 8 位访问的代码。
[编辑]:下面是我正在使用的 memcpy 代码
void* memcpy(void * restrict s1, const void * restrict s2, size_t n)
{
char* ll = (char*)s1;
char* rr = (char*)s2;
for (size_t i = 0; i < n; i++) ll[i] = rr[i];
return s1;
}
下面是代码的反汇编
void* memcpy3(void *s1, void *s2, size_t n)
{
char* ll = (char*)s1;
char* rr = (char*)s2;
for (size_t i = 0; i < n; i++) ll[i] = rr[i];
0: b38a cbz r2, 66 <memcpy3+0x66>
{
2: b4f0 push {r4, r5, r6, r7}
4: 1d03 adds r3, r0, #4
6: 1d0c adds r4, r1, #4
8: 42a0 cmp r0, r4
a: bf38 it cc
c: 4299 cmpcc r1, r3
e: d31e bcc.n 4e <memcpy3+0x4e>
10: 2a08 cmp r2, #8
12: d91c bls.n 4e <memcpy3+0x4e>
14: 460d mov r5, r1
16: 4604 mov r4, r0
for (size_t i = 0; i < n; i++) ll[i] = rr[i];
18: 2300 movs r3, #0
1a: 0897 lsrs r7, r2, #2
1c: f855 6b04 ldr.w r6, [r5], #4
20: 3301 adds r3, #1
22: 429f cmp r7, r3
24: f844 6b04 str.w r6, [r4], #4
28: d8f8 bhi.n 1c <memcpy3+0x1c>
2a: f022 0303 bic.w r3, r2, #3
2e: 429a cmp r2, r3
30: d00b beq.n 4a <memcpy3+0x4a>
32: 56cd ldrsb r5, [r1, r3]
34: 1c5c adds r4, r3, #1
36: 42a2 cmp r2, r4
38: 54c5 strb r5, [r0, r3]
3a: d906 bls.n 4a <memcpy3+0x4a>
3c: 570d ldrsb r5, [r1, r4]
3e: 3302 adds r3, #2
40: 429a cmp r2, r3
42: 5505 strb r5, [r0, r4]
44: d901 bls.n 4a <memcpy3+0x4a>
46: 56ca ldrsb r2, [r1, r3]
48: 54c2 strb r2, [r0, r3]
return s1;
}
4a: bcf0 pop {r4, r5, r6, r7}
4c: 4770 bx lr
4e: 3a01 subs r2, #1
50: 440a add r2, r1
52: 1e43 subs r3, r0, #1
54: 3901 subs r1, #1
for (size_t i = 0; i < n; i++) ll[i] = rr[i];
56: f911 4f01 ldrsb.w r4, [r1, #1]!
5a: 4291 cmp r1, r2
5c: f803 4f01 strb.w r4, [r3, #1]!
60: d1f9 bne.n 56 <memcpy3+0x56>
}
62: bcf0 pop {r4, r5, r6, r7}
64: 4770 bx lr
66: 4770 bx lr
是否可以将 arm-gcc 编译器配置为不对未对齐的地址使用 32 位访问。
解决方案
使用-mno-unaligned-access
标志告诉编译器不要使用非对齐访问。默认情况下,编译器使用-munaligned-access
.
推荐阅读
- python - 用字典解析多列表
- c# - 用户输入的字符串插值
- tensorflow-serving - 在 python 进程中直接使用 TensorFlow Serving 作为库
- kubernetes - 更改quarkus hazelcast集群成员ip
- python - Python在比较我的数据框中的两列后创建和追加行
- reactjs - “GET https://graph.microsoft.com/v1.0/me 401(未经授权)”:为什么我无法访问 Microsoft Graph API?
- axios - 从 axios 正文到输入下的打印错误
- javascript - 使用 Jquery 滑块过滤帖子
- swift - 将数据从 uipickerview 传递到 uilabel 的问题
- java - 在 Java 中创建一个通用的 InArray 方法