欢迎来到天天文库
浏览记录
ID:40559228
大小:25.41 KB
页数:12页
时间:2019-08-04
《Keil51有趣的特性》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库。
1、KeilC51的一些有趣特性时间:2005-06-0215:16:00来源:侃单片机作者:yanfengzhu首先得说的是我是菜鸟,在此论坛上学了很多的东东。但是今年以来,论坛上似乎没有了去年一大帮高手讨论问题的场面了,似乎失去了往日的风光了。在此我那出我近日一些不成熟的想法,希望大家斧正。有啥不正确的,请一定告之与我。KeilC51的一些有趣特性 作者:yanfengE-mail:szq106@163.com Keilc51号称作为51系列单片机最好的开发环境,大家一定都很熟悉。它的一些普通的特性
2、大家也都了解,(书上也都说有)如:因为51内的RAM很小,C51的函数并不通过堆栈传递参数(重入函数除外),局部变量也不存储在堆栈中,而是存在于固定的RAM中及寄存器中。那么看一下下面的程序。voidfun1(unsignedchari){ …}正常情况参数i通过R7传入函数,那么它的实际地址在什么地方呢?就是R7吗?回答这个问题之前我们先来了解keilc51的几个有趣的特性(不考虑重入函数)。 一、 函数在调用前定义与在调用后定义产生的代码是有很大差别的(特别是在
3、优化级别大于3级时)。(本人也不太清楚为什么,大概因为在调用前定义则调用函数已经知道被调用函数对寄存器的使用情况,则可对函数本身进行优化;而在调用后进行定义则函数不知被调用函数对寄存器的使用情况,它默认被调用函数对寄存器(ACC、B、DPH、DPL、PSW、R0、R1、R2、R3、R4、R5、,R6、R7)都已经改变,因此不在这些寄存器中存入有效的数据)二、 函数调用函数时除在堆栈中存入返回地址之外,不在堆栈中保存其它任何寄存器(ACC、B、DPH、DPL、PSW、R0、R1
4、、R2、R3、R4、R5、,R6、R7)的内容。(除非被调用函数使用了using特性)三、 中断函数是一个例外,它会计算自身及它所调用的函数对寄存器(ACC、B、DPH、DPL、PSW、R0、R1、R2、R3、R4、R5、,R6、R7)的改变,并保存相应它认为被改变了的寄存器。四、 使用C写程序时,尽量少使用usingn(n=0,1,2,3)特性。(这个特性在本人使用的过程中存在一些问题,不知算不算是一个小bug)以下的试验都是在(环境keilc51v
5、7.20)中,优化级为default下完成。 先看第一个特性问题。例1:voidfun2(void){} voidfun1(unsignedchari){ fun2(); while(i--);}它的汇编代码如下:;voidfun2(void) RSEG ?PR?fun2?TESTfun2: ;SOURCELINE#12;{ ;SOURCELINE#13;}
6、 ;SOURCELINE#14 RET ;ENDOFfun2 ;;voidfun1(unsignedchari) RSEG ?PR?_fun1?TEST_fun1: USING 0 ;SOURCELINE#16;----Variable'i?240'assignedtoRegister'R7'----;{ ;SOURCELINE#17; fun2();
7、 ;SOURCELINE#18 LCALL fun2?C0003:; while(i--); ;SOURCELINE#19 MOV R6,AR7 DEC R7 MOV A,R6 JNZ ?C0003;} ;SOURCELINE#20?C0005: RET ;ENDOF_f
8、un1从中可以看到fun2()在fun1()前先定义,fun1()知道fun2()对寄存器的使用情况,知道R7没有改变,而参数i存于R7中,即i既是R7。(;----Variable'i?140'assignedtoRegister'R7'----) 看另一情况voidfun2(void);voidfun1(unsignedchari){ fun2(); while(i--);} voidfun2(void){}汇编代码如下:;voidfun1(u
此文档下载收益归作者所有