使用keil AC6 编译器(关于一次数组越界的记录)

之前一直是用v5编译,编译速度慢,换成V6编译速度至少快3倍以上 ,而且 arm 后期只维护v6编译器,不再更新v5编译器

Keil MDK自 V5.36 版本之后,默认就不带 Arm Compiler V5版本编译器。如果需要使用 V5 版本编译器,就需要自己下载并安装

V5编译通过的工程,V6有可能编译不过去,就算能过,也不知道会不会出莫名其妙的问题,建议从头开始一个项目的时候使用这个方式。

使用v6编译器需要注意以下:

  • 配置优化选项

    http://t.csdnimg.cn/hqSvT

    http://t.csdnimg.cn/Jgs9T

  • 使用V6编译器有时候不能跳转到定义

    http://t.csdnimg.cn/81A3d

编译器不同,汇编结果不同

问题描述

当数组下标越界时,会触发 HardFault。在不改变代码逻辑,仅将编译器从 Keil ARM 编译器 V5 更换为 Keil ARM 编译器 V6(因为 V6 编译速度快了好几倍)后,代码崩溃并进入了 HardFault。

问题代码

涉及问题的代码如下:

OLED_ShowString(10, 15, g_motor_info_table[(g_menu_device.motor_index - 1) % MOTOR_ID_COUNT].name, OLED_6X8);

其中,g_motor_info_table 是在其他地方定义的全局结构体数组,而 g_menu_device.motor_index 这个变量在初始化时赋值为零。

分析

由于 g_menu_device.motor_index 的初始值为 0,当计算 (g_menu_device.motor_index - 1) 时,结果为 -1,进而作为下标访问 g_motor_info_table 数组时发生了越界访问。

在 STM32 Cortex-M4 微控制器中,RAM(包括 SRAM 及其他类型的 RAM)被映射到内存地址空间中,而 STM32F4 系列微控制器的内部 SRAM 起始地址为 0x20000000。
根据编译后程序内存的分布图(如下所示):

  • Keil ARM 编译器 V5:
    在这里插入图片描述
  • Keil ARM 编译器 V6:
    在这里插入图片描述
    在 ARM 编译器 V6 中,变量 g_menu_device.motor_index 的地址为 0x20000004。因此,当数组下标计算溢出导致访问地址低于 0x20000000 时,会访问到无效地址,从而引发 HardFault。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值