Linux踩坑:arm下gcc编译添加 -Ox 优化后,程序无法正常运行

arm下gcc编译添加 -Ox 优化后,程序无法正常运行

一、问题描述

今天学习正点原子的阿尔法开发板裸机开发的时候,遇到了一个问题,在没有使用 -Ox 优化的时候,编译出来的程序能够正常运行,但是添加了-Ox之后,程序运行就出了问题。

二、问题查找与解决

最开始还以为是自己敲的代码和视频中的代码出入比较大,影响到了程序的运行,不过事实证明(发现过程比较复杂,这里就不详写了),也确实是,下面是两者的差异代码,前者是我自己写的,后者是视屏中的:

//我写的
void Delay(volatile unsigned int n) {
    unsigned int n_s = 0;

    while(n --) {
        n_s = 0x7FF;
        while(n_s --);
    }
}
//官方例程
void Delay_Short(volatile unsigned int n)
{
    while(n--){}
}

void Delay(volatile unsigned int n) {
    while(n--) {
        Delay_Short(0x7ff);
    }
}

在逻辑上确实没啥大问题,但是编译出来的效果却截然不同,后者能够正常运行,前者运行就是异常的,最终发现,差异就在一个平时很少见的关键词 volatile,我写的 unsigned int n_s = 0; 就没有添加 volatile 前缀,后面把前缀加上,问题就解决了,程序也能正常运行了。

//以下代码能够正常运行
void Delay(volatile unsigned int n) {
    volatile unsigned int n_s = 0;

    while(n --) {
        n_s = 0x7FF;
        while(n_s --);
    }
}

三、总结

本次问题的最终问题就出在一个关键词上边,做了三年的嵌入式开发了,遇到使用 volatile 关键词来修饰的变量屈指可数,一直觉得这个关键词不重要,唯一影响深刻的就是在学习 stm32 的时候,正点原子介绍一种叫做位带操作的时候出现过一次,其他时候出现的概率都很小,不过最主要还是没遇到过 -Ox 这种编译优化,今天也是无意中遇到了,然后特意学习了一下,明白了大致原因,经过 -Ox 编译优化处理过后的一些数据会被一直放在寄存器中,内存不会对其进行再次写入操作,所以他的值得不到改变,所以最终导致了程序运行异常,这种操作叫做 内存覆盖,所以程序会运行异常。
在这里插入图片描述
在这里插入图片描述

参考博文:
1.《C语言关键字详解(五)带你全面了解 volatile 关键字》
https://blog.csdn.net/m0_62391199/article/details/123746218
2.《C语言丨深入理解volatile关键字》
https://blog.csdn.net/m0_53157173/article/details/129344954

学习分享,一起成长!以上为小编的经验分享,若存在不当之处,请批评指正!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是混子我怕谁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值