三九宝宝网宝宝百科宝宝知识

二级考试C++基础:volatile的使用方法

12月14日 编辑 39baobao.com

[儿童餐具使用方法]使用围嘴宝宝进餐前可先戴上围嘴,以减少弄脏衣服的机会。围嘴最好选用塑料或有塑料衬的布围嘴,可以防止菜汤渗透,同时清洁起来也较方便。[儿童餐具有什么作用]2准备专用餐桌...+阅读

volatile的本意是一般有两种说法--1.“暂态的”;2.“易变的”。

其实Volatile是由于编译器优化所造成的一个Bug而引入的关键字。

int a = 10;

int b = a;

int c = a;

理论上来讲每次使用a的时候都应该从a的地址来读取变量值,但是这存在一个效率问题,就是每次使用a都要去内存中取变量值,然后再通过系统总线传到CPU处理,这样开销会很大。所以那些编译器优化者故作聪明,把a读进CPU的cache里,像上面的代码,假如a在赋值期间没有被改变,就直接从CPU的cache里取a的副本来进行赋值。但是bug也显而易见,当a在赋给b之后,可能a已经被另一个线程改变而重新写回了内存,但这个线程并不知道,依旧按照原来的计划从CPU的cache里读a的副本进来赋值给c,结果不幸发生了。

于是编译器的开发者为了补救这一bug,提供了一个Volatile让开发人员为他们的过失埋单,或者说提供给开发人员了一个选择效率的权利。当变量加上了Volatile时,编译器就老老实实的每次都从内存中读取这个变量值,否则就还按照优化的方案从cache里读。

例1.

void main (void)

{

volatile int i;

int j;

i = 1; 1 不被优化 i=1

i = 2; 2 不被优化 i=1

i = 3; 3 不被优化 i=1

j = 1; 4 被优化

j = 2; 5 被优化

j = 3; 6 j = 3

}

例2.

函数:

void func (void)

{

unsigned char xdata xdata_junk;

unsigned char xdata *p =

unsigned char t1, t2;

t1 = *p;

t2 = *p;

}

编译的汇编为:

0000 7E00 R MOV R6,#HIGH xdata_junk

0002 7F00 R MOV R7,#LOW xdata_junk

;---- Variable ’p’ assigned to Register ’R6/R7’ ----

0004 8F82 MOV DPL,R7

0006 8E83 MOV DPH,R6

;!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 注意

0008 E0 MOVX A,#DPTR

0009 F500 R MOV t1,A

000B F500 R MOV t2,A

;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

000D 22 RET

将函数变为:

void func (void)

{

volatile unsigned char xdata xdata_junk;

volatile unsigned char xdata *p =

unsigned char t1, t2;

t1 = *p;

t2 = *p;

}

编译的汇编为:

0000 7E00 R MOV R6,#HIGH xdata_junk

0002 7F00 R MOV R7,#LOW xdata_junk

;---- Variable ’p’ assigned to Register ’R6/R7’ ----

0004 8F82 MOV DPL,R7

0006 8E83 MOV DPH,R6

;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

0008 E0 MOVX A,#DPTR

0009 F500 R MOV t1,A a处

000B E0 MOVX A,#DPTR

000C F500 R MOV t2,A

;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

000E 22 RET

比较结果可以看出来,未用volatile关键字时,只从*p所指的地址读一次

如在a处*p的内容有变化,则t2得到的则不是真正*p的内容。

例3

volatile unsigned char bdata var; use volatile keyword here

sbit var_0 = var^0;

sbit var_1 = var^1;

unsigned char xdata values[10];

void main (void) {

unsigned char i;

for (i = 0; i< sizeof (values); i++) {

var = values[i];

if (var_0) {

var_1 = 1; a处

values[i] = var; without the volatile keyword, the piler

assumes that ’var’ is unmodified and does not

reload the variable content.

}

}

}

在此例中,如在a处到下一句运行前,var如有变化则不会,如var=0xff; 则在

values[i] = var;得到的还是values[i] = 1;

应用举例:

例1.

#define DBYTE ((unsigned char volatile data *) 0)

说明:此处不用volatile关键字,可能得不到真正的内容。

例2.

#define TEST_VOLATILE_C

verwendete Include Dateien

#if __C51__< 600

#error: !! Keil 版本不正确

#endif

函数 void v_IntOccured(void)

extern void v_IntOccured(void);

变量定义

char xdata cvalue1; 全局xdata

char volatile xdata cvalue2; 全局xdata

函数: v_ExtInt0()

版本:

参数:

用途:cvalue1++,cvalue2++

void v_ExtInt0(void) interrupt 0 {

cvalue1++;

cvalue2++;

}

函数: main()

版本:

参数:

用途:测试volatile

void main() {

char cErg;

1. 使cErg=cvalue1;

cErg = cvalue1;

2. 在此处仿真时手动产生中断INT0,使cvalue1++; cvalue2++

if (cvalue1 != cErg)

v_IntOccured();

3. 使cErg=cvalue2;

cErg = cvalue2;

4. 在此处仿真时手动产生中断INT0,使cvalue1++; cvalue2++

if (cvalue2 != cErg)

v_IntOccured();

5. 完成

while (1);

}

函数: v_IntOccured()

版本:

参数:

用途: 死循环

void v_IntOccured() {

while(1);

}

仿真可以看出,在没有用volatile时,即2处,程序不能进入v_IntOccured();

但在4处可以进入v_IntOccured();

以下为关联文档:

宝宝防晒霜使用方法外出前20分钟涂抹最好宝宝防晒霜使用方法——家长提前计划好外出的大致时间,防晒霜至少需要15分钟才能被皮肤吸收,因此等到出门时才给孩子涂防晒霜就起不到作用了,所以给宝宝在...

宝宝定型枕的使用方法宝宝定型枕的使用方法一 枕头安全问题1、原因:宝宝们的安全是第一位的,枕头本身可能不会产生严重安全问题,但是由于宝宝自身不能调整睡眠姿势,所以睡眠姿势也可能引起窒息等安...

详解托福作文185道题库的使用方法12、标点问题例子:I love animals. And I like to help them. Because they are helpless. So I want to bee a vet.许多学生在句子中使用了太多的句号,尤其是当他们用手写...

商务礼仪中名片的使用方法名片使用 在国际交往中,没有名片的人,将被视为没有社会地位的人。一个不随身携带名片的人,是个不懂得尊重别人的人。名片不仅要有,而且要带着。在外国的企业公司,员工这个名片放...

夏天风油精使用方法夏天被蚊子叮,或者是简单护肤,让宝宝皮肤清爽。爸爸妈妈们会选择简单的风油精。对于一岁以内的宝宝来说,风油精、清凉油、花露水这类有刺激性的外用搽剂使用时必须要特别的注意...

飞利浦新安怡吸乳器正确使用方法如何使用吸奶器 1、洗净双手和乳房。从每个乳房中轻轻挤出一点乳汁以确保乳腺没有堵塞; 2、确保你已经将吸奶器消过毒并且安装好了; 3、使用吸奶器之前看看使用小窍门; 4、选择...

C++技巧:emacs完美的C++的自动补全1,CVS cedet的最新代码,1.04代码补全很慢。 cvs -z3 -d:pserver:anonymous#cedet.cvs.sourcefe.:/cvsroot/cedet co -P cedet 2,命令行运行 touch `find -name "Makefile"` (注...

与动词时态相关的句子结构及关键词使用方法一般现在时: 句子结构: 肯定句 主语+be (am, is, are ) + 其他 否定句 主语+be not +其他 疑问句 Be+主语+其他 或: 肯定句 主语+动词原型+其他 ( 第三人称单数作主语动词要...

塑料管材的特点使用方法及注意事项随着人们生活水平、环保意识的提高以及对健康的关注,在给排水领域掀起了一场建材行业的绿色革命。据大量水质监测数据表明:采用冷镀锌钢管后,一般使用寿命不到5年就锈蚀,铁腥味...

推荐阅读
图文推荐