使用-O2时的ARM GCC硬故障

时间:2018-09-01 18:21:43

标签: gcc optimization arm

在优化级别为-O2(及更高版本)的情况下使用ARM GCC g ++编译器时,此代码:

void foo(void)
{
    DBB("@0x%08X: 0x%08X", 1, *((uint32_t *)1));
    DBB("@0x%08X: 0x%08X", 0, *((uint32_t *)0));
}

编译为:

0800abb0 <_Z3foov>:
 800abb0:   b508        push    {r3, lr}
 800abb2:   2301        movs    r3, #1
 800abb4:   4619        mov r1, r3
 800abb6:   681a        ldr r2, [r3, #0]
 800abb8:   4802        ldr r0, [pc, #8]    ; (800abc4 <_Z3foov+0x14>)
 800abba:   f007 fa83   bl  80120c4 <debug_print_blocking>
 800abbe:   2300        movs    r3, #0
 800abc0:   681b        ldr r3, [r3, #0]
 800abc2:   deff        udf #255    ; 0xff
 800abc4:   08022704    stmdaeq r2, {r2, r8, r9, sl, sp}

这使我在未定义的指令@ 0x0800abc2上遇到了硬故障。 另外,如果之后没有更多代码,则不会将其编译为最终二进制文件。

问题是为什么编译器会这样生成它,为什么会有未定义的指令?

顺便说一句,它可以很好地用于这样的事情:

...
uint32_t num = 2;
num -= 2;
DBB("@0x%08X: 0x%08X", 0, *((uint32_t *)num));
...

编译器版本:

arm-none-eabi-g++.exe (GNU Tools for ARM Embedded Processors 6-2017-q2-update) 6.3.1 20170620 (release) [ARM/embedded-6-branch revision 249437]

1 个答案:

答案 0 :(得分:1)

您可以使用-fno-delete-null-pointer-checks

禁用此功能(并验证此答案)

您传递的指针具有与空指针匹配的值,并且编译器可以从静态分析中看到该值,因此会出错(因为这是定义的行为)。

在第二个示例中,静态分析无法识别NULL。