arm - Linaro g++ aarch64 编译导致未对齐错误

标签 arm g++ memory-alignment arm64

我正在使用 ARM arch64 的 linaro g++ 来编译一个简单的 cpp 文件:

int main()
{
    char  *helloMain      = "main module (crm.c)";
    long  faculty, num    = 12;
    int   stop,mainLoop   = 1; 
    char  word[80]        = "";
}

objdump生成的elf文件后,我得到了它的asm代码:

0000000000001270 <main>:
int main()
{
    1270:   d101c3ff    sub sp, sp, #0x70
    char  *helloMain      = "main module (crm.c)";
    1274:   90000020    adrp    x0, 5000 <_malloc_trim_r+0x160>
    1278:   9111c000    add x0, x0, #0x470
    127c:   f90003e0    str x0, [sp]
    long  faculty, num    = 12;
    1280:   d2800180    movz    x0, #0xc
    1284:   f90007e0    str x0, [sp,#8]
    int   stop,mainLoop   = 1; 
    1288:   52800020    movz    w0, #0x1
    128c:   b90013e0    str w0, [sp,#16]
    char  word[80]        = "";
    1290:   910063e0    add x0, sp, #0x18
    1294:   90000021    adrp    x1, 5000 <_malloc_trim_r+0x160>
    1298:   91122021    add x1, x1, #0x488
    129c:   39400021    ldrb    w1, [x1]
    12a0:   39000001    strb    w1, [x0]
    12a4:   91000400    add x0, x0, #0x1
    12a8:   a9007c1f    stp xzr, xzr, [x0]
    12ac:   a9017c1f    stp xzr, xzr, [x0,#16]
    12b0:   a9027c1f    stp xzr, xzr, [x0,#32]
    12b4:   a9037c1f    stp xzr, xzr, [x0,#48]
    12b8:   f900201f    str xzr, [x0,#64]
    12bc:   b900481f    str wzr, [x0,#72]
    12c0:   7900981f    strh    wzr, [x0,#76]
    12c4:   3901381f    strb    wzr, [x0,#78]
}
    12c8:   52800000    movz    w0, #0x0
    12cc:   9101c3ff    add sp, sp, #0x70
    12d0:   d65f03c0    ret

在 ARMV8 板上执行此代码之前,sp 被初始化为与 0x1000 对齐的地址。

此类代码的执行引发了对齐错误异常 12a8: a9007c1f stp xzr, xzr, [x0]

我注意到 x0 是由 0x1 添加的,因此在执行 stp 指令时它与 0x1 对齐。

为什么 g++ 没有让它对齐到 0x10 以避免这种对齐错误异常?

g++ 版本是:

gcc  4.8.1 20130506 (prerelease) (crosstool-NG linaro-1.13.1-4.8-2013.05 - Linaro GCC 2013.05)

最佳答案

来自 the manual :

-munaligned-access
-mno-unaligned-access

Enables (or disables) reading and writing of 16- and 32- bit values from addresses that are not 16- or 32- bit aligned. By default unaligned access is disabled for all pre-ARMv6 and all ARMv6-M architectures, and enabled for all other architectures. If unaligned access is not enabled then words in packed data structures will be accessed a byte at a time.

The ARM attribute Tag_CPU_unaligned_access will be set in the generated object file to either true or false, depending upon the setting of this option. If unaligned access is enabled then the preprocessor symbol __ARM_FEATURE_UNALIGNED will also be defined.

AArch64/ARMv8 支持开箱即用的未对齐访问,因此 GCC 假定它可用。如果不是这种情况,您可能必须使用上述开关明确禁用它。也有可能您正在使用的“预发布”版本尚未完全完成,并且存在各种错误/问题。

编辑

评论中提到,对应的AArch64 options是:

-mstrict-align
-mno-strict-align

Avoid or allow generating memory accesses that may not be aligned on a natural object boundary as described in the architecture specification.

顺便说一句,代码的行为是这样的,因为 GCC 按字面解释赋值:

  1. 将字符串“”(因此只有一个零字节)复制到缓冲区的开头。
  2. 用零填充缓冲区的其余部分。

我怀疑如果启用优化,未对齐的访问将会消失。 或者,如果您使用 char word[80] = {0},它应该一次性完成归零。

关于arm - Linaro g++ aarch64 编译导致未对齐错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23266411/

相关文章:

c++ - 对齐数据: speed dependance on relative sampling size vs sampling frequency on a constant data read

debugging - ARM Gdb 在处理器模式更改时中断

linux - 使用 arm-none-linux-gnueabi-gcc 的冲突架构配置文件 A/M 错误

c++ - 对符号 'XF86VidModeQueryExtension' 的 undefined reference (linux、qt creator IDE)

python - 如何使用 python 结构将结构打包到结构中?

c++ - "points to uninitialised byte(s)"Valgrind 错误

c++ - 嵌入式 C++ (ARM9) 单元测试

c - STM32F103如何使用ENC28j60

C++ 在 Linux/Ubuntu 中写入文件错误?

c++ - 线程本地存储构造函数 g++