我用keil的软件仿真运行如下代码
void main
{
unsigned int t;
t = 0x8000 + 0x5555;
*(unsigned char *)t = 0xaa;
}
t = 0x8000 + 0x5555这条语句不执行。只能执行*(unsigned char *)t = 0xaa;
这是为什么?谢谢!
void main
{
unsigned int t;
t = 0x8000 + 0x5555;
*(unsigned char *)t = 0xaa;
}
应该不是优化的问题吧
若被优化了,0xaa写到什么地方了
是语句t = 0x8000 + 0x5555;被优化了,不是t被优化掉了。
我的目的是将0xaa写到0x8000 + 0x5555的地址。怎么关闭优化,XDATA宏是什么意思。谢谢!
zhuoyuesky(卓越) ( ) 信誉:100 Blog 2007-03-23 12:17:46 得分: 0
voliate是什么,如何使用,初学51。谢谢!
............................................
这个是说告诉编译器,该变量是经常使用的,一般会为这个做特殊物理,比如说放入CPU的缓存,以减小访问的代价,增加执行效率
t = 0x8000 + 0x5555这条语句不执行。只能执行*(unsigned char *)t = 0xaa;
这是为什么?谢谢!
因为,现在的编译器已经足够智能,只要编译的时候把T放到0x8000 + 0x5555这个地址上,这就可以省掉一个运算,提高程序的执行效率!!
从另一个侧面可以说是编译器生成代码的质量很高
zhuoyuesky(卓越) ( ) 信誉:100 Blog 2007-03-23 12:17:46 得分: 0
voliate是什么,如何使用,初学51。谢谢!
............................................
这个是说告诉编译器,该变量是经常使用的,一般会为这个做特殊物理,比如说放入CPU的缓存,以减小访问的代价,增加执行效率
==================================================================
不要误导新网友!
>>t = 0x8000 + 0x5555这条语句不执行。只能执行*(unsigned char *)t = 0xaa;
这是为什么?谢谢!
编译器能将这一条语句优化掉!可能吗,智能到将一条正确而且并不是冗余的一条语句删掉.建议你看看程序其他地方有没有问题,或者关掉编译器重启试一下,这个问题最简单的办法是查看生成的对应汇编语言,看看有没有这条语句,没有那就是被优化掉了
zhuoyuesky(卓越) ( ) 信誉:100 Blog 2007-03-23 12:17:46 得分: 0
voliate是什么,如何使用,初学51。谢谢!
............................................
这个是说告诉编译器,该变量是经常使用的,一般会为这个做特殊物理,比如说放入CPU的缓存,以减小访问的代价,增加执行效率
==================================================================
不要误导新网友!
同意,正好说反了
voliate 不是常用量,是易变量,如端口。处理时不做一些默认优化。
对不起,重新找了相关的书籍后...
我是错的,谢谢大家指正,同时也谢谢LZ让我发现在我的知识结构中还有这样低级的缺陷,
呵呵,学习
但是,之后我说的下面这句被优化掉了,这个是正确的!
t = 0x8000 + 0x5555这条语句不执行。只能执行*(unsigned char *)t = 0xaa;
请看:
void main()
{
unsigned int t;
t = 0x8000 + 0x5555;
*(unsigned char *)t = 0xaa;
}
这是它的C代码
C:0x0021 7AD5 MOV R2,#0xD5
C:0x0023 7955 MOV R1,#0x55
C:0x0025 7B00 MOV R3,#0x00
C:0x0027 74AA MOV A,#0xAA
这是生成的汇编,连t这个变量都没有存在的迹像
所以,我的没错,的确是被编译器干掉了
为了向楼主和大家诚心地赔不是,我自己理解了但为了解决最终的问题,我也把分析结果大家分享一下吧...
void main()
{
volatile unsigned int t;
t = 0x8000 + 0x5555;
*(unsigned char *)t = 0xaa;
}
这是加了volatile声明后,看编译器生成的代码
3: volatile unsigned int t;
4:
5: t = 0x8000 + 0x5555;
C:0x0003 900000 MOV DPTR,#C_STARTUP(0x0000)
C:0x0006 74D5 MOV A,#0xD5
C:0x0008 F0 MOVX @DPTR,A
C:0x0009 A3 INC DPTR
C:0x000A 7455 MOV A,#0x55
C:0x000C F0 MOVX @DPTR,A
6: *(unsigned char *)t = 0xaa;
C:0x000D 900000 MOV DPTR,#C_STARTUP(0x0000)
C:0x0010 E0 MOVX A,@DPTR
C:0x0011 FE MOV R6,A
C:0x0012 A3 INC DPTR
C:0x0013 E0 MOVX A,@DPTR
C:0x0014 AA06 MOV R2,0x06
C:0x0016 F9 MOV R1,A
C:0x0017 7B00 MOV R3,#0x00
C:0x0019 74AA MOV A,#0xAA
C:0x001B 02001E LJMP C?CSTPTR(C:001E)
可以清楚地看到,编译器还是把加法干掉,只留下变量t,直接事先把计算好的值送入t(地址为片外的0x0000)注:在编译的时候我把RAM设为LARGE模式,所以直接放到片外去了
这时候可以看到,虽然t没有什么意义,但是编译器还是留下了它...
这也就加深体会了我对volatile的理解
晕,很简单的事,对于嵌入式来说,voliate告诉编译器此变量里的值不确定,会偷偷变化,编译器在没次使用的时候要重新确认数据后再进行操作,不能使用任何中间的缓存数据,也不能做任何优化,但这与编译器优化级别设置有关。
unsigned int t;
t = 0x8000 + 0x5555;
*(unsigned char *)t = 0xaa;
翻译一下:
*((unsigned char *)(unsigned int(0x8000 + 0x5555))) = 0xaa;
对Xram 赋值的意思
0x8000 + 0x5555直接就是一个数么,不被优化掉编译器岂不是太傻?