c语言 编译器关键字,C语言中volatile关键字的使用

本文详细解释了volatile关键字的作用及其在C51程序中的具体应用。通过对比优化前后代码,阐述了volatile如何防止编译器对某些变量进行优化,确保变量值在多任务环境或中断服务程序中的正确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

volatile的意思是易变的、可变的,作用是限制编译器优化某些变量。首先看一段C51程序:

efd7ae01269195de17ddbc31f3c91274.png

480c992a664dd9545c272b446ccfc5a1.png

Keil在优化级别是为8时得到如下汇编代码(部分未列出):

18028645e8e5067490365a9288a7daa6.png

可以看到,变量d的值赋给x,y,z时,只有x中是直接读取的d中数值,而y=d,z=d则直接将寄存器中的数值赋给y,z。若在此过程中,变量d的值被改变(比如d是一个硬件寄存器),则y,z变量中得到的数据将是错误的,因此在某些应用中程序存在隐患。

这类问题并不是编译器的问题。由于访问内部寄存器比访问RAM速度块,因此编译器在编译类似程序时,会对程序进行优化,除第一次编译变量所在在连续读取一个变量时,编译器为了简化程序,只要有可能就会把第一次读取的值放在ACC或Rx中,在以后的读取该变量的值时就直接使用第一次的读取值。如果该变量的值在此过程中已经被外设(如读取外部设备端口时经常将外设端口看作一外部RAM地址)或其他程序(如中断服务程序)所改变,可能就会出错。为了解决这类问题,常用的方法就是降低编译器的优化级别或者使用volatile关键字。显然降低优化级别不是所期望的,因此用volatile关键字修饰相关变量很有必要。

上文中的例子将d加上volatile关键字后,如下:

13032316412573.jpg

dfe05d2e5be5e309966802e603d8ff31.png

重新编译得到的代码(部分未列出)如下:

37969ba154e7cb0fd407a9729aaf096d.png

可以看这此y,z变量的值是从d的存储区中读取的。这主要是由编译器的优化早成的,而不是编译器的错误。用volatile变量对变量d修饰后,编译器不对这个变量的操作进行优化,代码的执行达到期望的目的。

一般说来,volatile关键字用在如下的几个地方。

(1)中断服务程序中修改的供其他程序检测的变量需要加volatile。

(2)多任务环境下各任务间共享的标志应该加volatile。

(3)存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能有不同意义。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值