51平台下初始化文件的引入导致全局变量无法初始化的问题
来源:互联网 发布:运营数据分析报告模板 编辑:程序博客网 时间:2024/05/16 17:24
写在前面
-----------------
在前段时间的工作中,就遇见过全局变量无法初始化的问题,不过之前是在一些C文件中定义的变量能初始化,而其他C文件中不能初始化,当时将这个问题绕过去了,并没有去深究...而这一周又出现了这个问题。于是就有了这篇文章
这里不去讨论其他情况下全局变量无法初始化的问题,只是针对我所遇见的问题讨论....
原因:由于引入库文件INIT.A51和STARTUP.A51导致的, 这里之所以要引入这两个文件,是由我们的应用环境决定的,如果在实际过程中没有手动引入这两个文件到工程项目中,则不会出现我这里提到的类似问题。
简述如下:
mcu复位后 PC=0 先执行STARTUP.A51的相关文件,该文件主要是对IDATA XDATA PDATA清零以及初始化堆栈指针;附上网络上一篇文章对其的讲解之部分关键代码:
; STARTUP.A51: 用户上电初始化程序
;------------------------------------------------------------------------------
;
; 用户定义需上电初始化的内存空间
;
; 使用以下EQU命令可定义在CPU复位时需用0进行初始化的内存空间
;
;;
; IDATA 存储器的空间的绝对起始地址总是0.;
IDATALEN EQU 80H ; 需用0进行初始化的IDATA存储器空间的字节数
;
XDATASTART EQU 0H ; XDATA存储器空间的绝对起始地址
XDATALEN EQU 400H ; 需用0进行初始化的XDATA存储器的空间字节数.
;
PDATASTART EQU 0H ; PDATA存储器的空间的绝对起始地址
PDATALEN EQU 0H ; 需用0进行初始化的PDATA存储器的空间字节数.
;
; 注意: IDATA 存储器的空间在物理上包括了8051单片机的DATA和BIT存储器空间.
; 听 说 至少要保证与C51编译器运行库有关的存储器的空间进行0初始化 不知是否
;------------------------------------------------------------------------------
;
; 再入函数模拟初始化
;
; 以下用EQU指令定义了再入函数模拟堆栈指针的初始化
;
; 使用SMALL存储器模式时再入函数的堆栈空间 .
IBPSTACK EQU 0 ; 使用SMALL存储器模式再入函数时将其设置成1.
IBPSTACKTOP EQU 0FFH+1 ; 将堆栈顶设置为最高地址+1.
;
; 使用LARGE存储器模式时再入函数的堆栈空间.; 使用LARGE存储器模式时再入函数的堆栈空间.
XBPSTACK EQU 0 ; 使用LARGE存储器模式再入函数时将其设置成1.
XBPSTACKTOP EQU 0FFFFH+1; 将堆栈顶设置为最高地址+1.
;
; 使用COMPACT存储器模式时再入函数的堆栈空间.; 使用COMPACT存储器模式时再入函数的堆栈空间.
PBPSTACK EQU 0 ; 使用COMPACT存储器模式再入函数时将其设置成1.
PBPSTACKTOP EQU 0FFFFH+1; 将堆栈顶设置为最高地址+1.
;
;------------------------------------------------------------------------------
;
; 使用COMPACT存储器模式时64K字节XDATA存储器空间的分页定义
;
; 以下用EQU指令定义PDATA类型变量在XDATA存储器空间的页地址
; 使用EQU指令定义PFAGE时必须与L51连接定位器PDATA指令的控制参数一致
;
PPAGEENABLE EQU 0 ; 使用PDATA类型变量时将其设置成1.
PPAGE EQU 0 ; 定义页号.
;
;------------------------------------------------------------------------------
.....
.....
.....
; RSEG ?STACK ; 堆栈
; DS 1
.....
.....
.....
CSEG AT 0x0000 ; 定义用户程序的起始地址
?C_STARTUP: LJMP STARTUP1
.....
.....
.....
; 设置堆栈的起始地址
MOV SP,#?STACK-1 ; 例如 MOV SP,#4FH;
.....
.....
.....
; 跳转到ININ.A51的初始化入口?C_START
LJMP ?C_START
END
由代码可知,在执行完清零操作后,程序将跳转到?C_START标号处,该程序标号定义在INIT.A51文件中,文件INIT.A51完成全局变量的初始化,其中包含有如下代码:
...
RSEG ?C_C51STARTUP
INITEND: LJMP MAIN
...
...
...
?C_START:
MOV DPTR,#?C_INITSEG
Loop:
WATCHDOG
CLR A
MOV R6,#1
MOVC A,@A+DPTR
JZ INITEND
INC DPTR
MOV R7,A
ANL A,#3FH
...
...
...
...
RSEG ?C_INITSEG
DB 0
...
...
其中#?C_INITSEG为编译生成的初始化段,该段保存了需要初始化的变量信息,可以看出上面的代码是利用该段的信息对相应变量进行初始化,注意其中的'JZ INITEND'(判断初始化段的相关位置为零则结束初始化);而INIT.A51文件的最后位置有'RSEG ?C_INITSEG';和'DB 0',所以问题的答案就在这里了!
问题出在INIT.A51在整个工程文件中的位置,假如在整个工程文件的最开始就编译INIT.A51,那么则'?C_INITSEG'第一个字节就是'0',所以接下来的初始化信息都不会被执行,解决办法就是INIT.A51最后才加入整个工程中,确保在该文件中加入'?C_INITSEG'段中的'0'是加在整个'?C_INITSEG'段的最后一个位置....
- 51平台下初始化文件的引入导致全局变量无法初始化的问题
- javascript中全局变量无法正常初始化的问题解疑
- initWithNibName导致的初始化问题
- initWithNibName导致的初始化问题
- initWithNibName导致的初始化问题
- 全局变量的初始化
- 全局变量的初始化
- 全局变量和静态变量的初始化问题
- 谈谈全局变量、静态变量的初始化问题
- 解决静态全局变量初始化的相互依赖问题
- C++全局变量初始化引发的问题
- 串口初始化 需要引入的头文件
- 解决AndroidStudio引入Lambda之后导致ButterKnife8.4.0版本无法初始化View问题
- 初始化和未初始化的全局变量
- 解决Windows下pyspark无法初始化SparkContext(sc)的问题
- C语言全局变量的初始化
- tensorflow里的全局变量初始化
- 错误初始化参数导致无法启动的解决办法
- ActiveX
- 终于不用天天带那副眼镜了
- 初涉flex
- 如何优化MyEclipse
- #pragma与__pragma的区别与联系
- 51平台下初始化文件的引入导致全局变量无法初始化的问题
- 今天开通了CSDN
- GROOVY对象模型
- 对mysql的order by及limit优化要适数据情况而定
- 李兆基:小生意要勤奋大生意要计算精确
- 【转】内存池&经典的内存池技术
- 从 VC6到VC9移植代码问题总结收藏
- 编写多线程Java应用程序常见问题
- 使用GTK+和Glade快速开发Linux图形界面