首先,这里的全局变量指的是 在main() 之前定义的变量(包括在 .h文件 或者 其他.c文件里面定义的变量)。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
假设没有加入startup.a51 文件(即使加入了,还是有这个问题),如果全局变量在定义的时候,没有被初始化。那么,实际生产的汇编代码 会是以下这样的流程:
从0000H开始(这里一般是一条跳转语句),然后执行对内部RAM的清零工作;而后,设置堆栈指针SP(系统上电的时候 SP="07H",但是编译之后,由于全局变量的影响,清零内部RAM之后,SP的位置不一定是SP);再然后,PC指针直接转去执行main()。
如果全局变量被初始化了,则生成的汇编代码是以下的情形:
从0000H开始(这里一般是一条跳转语句),然后执行对内部RAM的清零工作;而后,设置堆栈指针SP(系统上电的时候 SP="07H",但是编译之后,由于全局变量的影响,清零内部RAM之后,SP的位置不一定是SP);然后,PC指针并没有转去main()! ----UV2,UV3 都是这个情况。
而是转去执行一大堆指令(被初始化的全局变量越多,这堆指令越长…指令看上去与init.a51这个文件有关—但是工程里并没有包含这个文件!无语…),最后才转去执行main().
------ 试图从这堆“冗余”的指令去看出点名堂,发现 里面居然有MOVC 这样的指令,似乎是在对某操作码进行运算…百思不得其解。
------### 暂且阁下这个事。
为了找回这些被莫名其妙就占去的code空间,可以使用下面的方法:
在main()外面,只声明变量,绝不初始化。
----注:类似sbit P1_0 = P1^0; 的语句不会引起这样的问题。
等到了main()里面,其他函数执行之前,再对全局变量初始化。
---对于 .h 或者其他 ,c文件里面的全局变量,也要如此处理。
======== 呵呵 当然,汇编高手可以完全不管这个东西 ====
=============================================================
=============================================================
刚翻出来看 INIT.A51 文件,一切谜团揭晓~~ 下面的内容摘自该文件说明:
INIT.A51: This code is executed, if the application program contains
; initialized variables at file level.
; User-defined Watch-Dog Refresh.
;
; If the C application contains many initialized variables uses a watchdog
; it might be possible that the user has to include a watchdog refresh into
; the initialization process. The watchdog refresh routine can be included
; in the following MACRO and can alter all CPU registers except
; DPTR.
;
WATCHDOG MACRO
; Include any Watchdog refresh code here
ENDM
------------------
看来keilC做的不完全是无用功... 全局变量还是少用为妙
用户433198 2013-12-20 09:58
用户377235 2013-9-29 08:53
太谢谢博主的提示了,终于可以省下一些重要的code空间
用户1432715 2011-8-26 10:21