假如说在keil中定义了一个全局变量int i = 0x1234;这个i的初始化肯定是在上电之后,main函数之前。编译完之后debug,从地址0开始执行,怎么没看见对i的初始化呢?有的说是在init.a51文件之中。但是一直没有找到明确的解释。
请高手明示!最后能帖段代码,谢谢了!
19 个解决方案
#1
楼主的意思我没太看明白,暂时按照我的理解解释:
这个变量的初始化跟上电没关系, 编译完成后就完成了对全局变量的初始化,这个初始化的全局变量被放在数据段。单片机要做的只是顺着地址执行代码。并不是说 i的初始化写在代码的前面 烧录时就放在低地址处 ,这个变量的初始化由编译器完成,并把它放到数据段 ,你看不到它执行初始化的过程
这个变量的初始化跟上电没关系, 编译完成后就完成了对全局变量的初始化,这个初始化的全局变量被放在数据段。单片机要做的只是顺着地址执行代码。并不是说 i的初始化写在代码的前面 烧录时就放在低地址处 ,这个变量的初始化由编译器完成,并把它放到数据段 ,你看不到它执行初始化的过程
#2
;-------------------------------------------------------------------------
; STRUCTURE OF THE INITIALIZATION INFORMATION
; -------------------------------------------
; This section describes the initialization data generated by C51 for
; explicit variable initializations (in segment ?C_INITSEC).
;
; Explicit variable initilizations at C source level are stored by C51 in
; the segment ?C_INITSEC. All partial segments are combined at linker level
; to one segment. The segment end value DB 0 is taken from this library module
; INIT.A51.
;
; Structure of the ?C_INITSEC information:
; <Info> (see below) [BYTE] ----+ repeated
; <additional info> [BYTES depend on Info] ----+ repeated
; 0x00 [BYTE] <end of list mark>
;
; <Info> has the following format:
;
; Bit 7 6 5 4 3 2 1 0
; <Info> T T B L L L L L T=Type B=BIGBIT L=LENGTH
;
; If BIGBIT is set, another LENGTH BYTE FOLLOWS. The LENGHT
; info of the first byte is then the HIGH part.
;
; Typ is one of the following:
; 0 := IDATA init values; the following bytes follow:
; - 1 byte address
; - init data bytes according LENGTH specification
;
; 1 := XDATA init values; the following bytes follow:
; - 2 byte address (high byte first)
; - init data bytes according LENGTH specification
;
; 2 := PDATA init values; the following bytes follow:
; - 1 byte address
; - init data bytes according LENGTH specification
;
; 3, BIGBIT=0 := BIT init values; the followign bytes follow:
; - 1 byte for each bit according LENGTH specification
; this byte has the following format:
;
; Bit 7 6 5 4 3 2 1 0
; I B B B B B B B I := state of the bit
; B := bit address
;
; 3, BIGBIT=1 := HDATA init values; the following bytes follow:
; - another LENGTH byte (since BIGBIT is always 1)
; - 3 byte address (MSB first)
; - data bytes according LENGTH specification
;
;----------------------------------------------------------------------
; STRUCTURE OF THE INITIALIZATION INFORMATION
; -------------------------------------------
; This section describes the initialization data generated by C51 for
; explicit variable initializations (in segment ?C_INITSEC).
;
; Explicit variable initilizations at C source level are stored by C51 in
; the segment ?C_INITSEC. All partial segments are combined at linker level
; to one segment. The segment end value DB 0 is taken from this library module
; INIT.A51.
;
; Structure of the ?C_INITSEC information:
; <Info> (see below) [BYTE] ----+ repeated
; <additional info> [BYTES depend on Info] ----+ repeated
; 0x00 [BYTE] <end of list mark>
;
; <Info> has the following format:
;
; Bit 7 6 5 4 3 2 1 0
; <Info> T T B L L L L L T=Type B=BIGBIT L=LENGTH
;
; If BIGBIT is set, another LENGTH BYTE FOLLOWS. The LENGHT
; info of the first byte is then the HIGH part.
;
; Typ is one of the following:
; 0 := IDATA init values; the following bytes follow:
; - 1 byte address
; - init data bytes according LENGTH specification
;
; 1 := XDATA init values; the following bytes follow:
; - 2 byte address (high byte first)
; - init data bytes according LENGTH specification
;
; 2 := PDATA init values; the following bytes follow:
; - 1 byte address
; - init data bytes according LENGTH specification
;
; 3, BIGBIT=0 := BIT init values; the followign bytes follow:
; - 1 byte for each bit according LENGTH specification
; this byte has the following format:
;
; Bit 7 6 5 4 3 2 1 0
; I B B B B B B B I := state of the bit
; B := bit address
;
; 3, BIGBIT=1 := HDATA init values; the following bytes follow:
; - another LENGTH byte (since BIGBIT is always 1)
; - 3 byte address (MSB first)
; - data bytes according LENGTH specification
;
;----------------------------------------------------------------------
#3
51我用的不多,AVR常用,现在大部分编译器都会在Main之前插入一段代码,用于初始化,包括全局变量赋值等。编译完后,你Main函数对应的入口地址并不在程序存储器的0地址处,因为那里是初始化代码(其实还有一段中断向量跳转代码)
#4
代码都是烧写在ROM中的,而全局之类的变量都是在RAM中,所以上电的时候肯定要初始化的。我知道编译器肯定要在main之前加入初始化代码的,但是我不知道加在哪儿了?在keil 中debug后的汇编后的汇编中似乎看不见呢。
#5
这个文件我知道,我想知道的后编译后这段代码插在生成汇编代码的哪个地方了。
#6
有没有被优化掉?
#7
一般来说,全局变量如果有初始值,它们会被存放在ROM的某个区域,上电后会执行一段从ROM到RAM复制的过程.....这就是全局变量的初始化.
#8
很简单,汇编是从0地址开始,而c的main函数不是从0地址开始的
初始化在main之前,因为在main之前有启动代码和初始化代码
#9
支持8楼!
#10
在startup.a51的最后,有这么一句 LJMP ?C_START,单步过去....
C:0x0626 020664 LJMP C:0664
C:0x0664 90099D MOV DPTR,#0x099D
C:0x0667 E4 CLR A
C:0x0668 7E01 MOV R6,#0x01
C:0x066A 93 MOVC A,@A+DPTR
C:0x066B 60BC JZ C:0629
C:0x066D A3 INC DPTR
C:0x066E FF MOV R7,A
C:0x066F 543F ANL A,#vbatt(0x3F)
C:0x0671 30E509 JNB 0xE0.5,C:067D
C:0x0674 541F ANL A,#0x1F
C:0x0676 FE MOV R6,A
C:0x0677 E4 CLR A
C:0x0678 93 MOVC A,@A+DPTR
C:0x0679 A3 INC DPTR
C:0x067A 6001 JZ C:067D
C:0x067C 0E INC R6
C:0x067D CF XCH A,R7
C:0x067E 54C0 ANL A,#0xC0
C:0x0680 25E0 ADD A,ACC(0xE0)
C:0x0682 60A8 JZ C:062C
C:0x0684 40B8 JC C:063E
C:0x0686 E4 CLR A
C:0x0687 93 MOVC A,@A+DPTR
C:0x0688 A3 INC DPTR
C:0x0689 FA MOV R2,A
C:0x068A E4 CLR A
C:0x068B 93 MOVC A,@A+DPTR
C:0x068C A3 INC DPTR
C:0x068D F8 MOV R0,A
C:0x068E E4 CLR A
C:0x068F 93 MOVC A,@A+DPTR
C:0x0690 A3 INC DPTR
C:0x0691 C8 XCH A,R0
C:0x0692 C582 XCH A,DPL(0x82)
C:0x0694 C8 XCH A,R0
C:0x0695 CA XCH A,R2
C:0x0696 C583 XCH A,DPH(0x83)
C:0x0698 CA XCH A,R2
C:0x0699 F0 MOVX @DPTR,A
C:0x069A A3 INC DPTR
C:0x069B C8 XCH A,R0
C:0x069C C582 XCH A,DPL(0x82)
C:0x069E C8 XCH A,R0
C:0x069F CA XCH A,R2
C:0x06A0 C583 XCH A,DPH(0x83)
C:0x06A2 CA XCH A,R2
C:0x06A3 DFE9 DJNZ R7,C:068E
C:0x06A5 DEE7 DJNZ R6,C:068E
C:0x06A7 80BE SJMP C:0667........然后就跳到main了....
全局变量初始化代码就在这里面......
C:0x0626 020664 LJMP C:0664
C:0x0664 90099D MOV DPTR,#0x099D
C:0x0667 E4 CLR A
C:0x0668 7E01 MOV R6,#0x01
C:0x066A 93 MOVC A,@A+DPTR
C:0x066B 60BC JZ C:0629
C:0x066D A3 INC DPTR
C:0x066E FF MOV R7,A
C:0x066F 543F ANL A,#vbatt(0x3F)
C:0x0671 30E509 JNB 0xE0.5,C:067D
C:0x0674 541F ANL A,#0x1F
C:0x0676 FE MOV R6,A
C:0x0677 E4 CLR A
C:0x0678 93 MOVC A,@A+DPTR
C:0x0679 A3 INC DPTR
C:0x067A 6001 JZ C:067D
C:0x067C 0E INC R6
C:0x067D CF XCH A,R7
C:0x067E 54C0 ANL A,#0xC0
C:0x0680 25E0 ADD A,ACC(0xE0)
C:0x0682 60A8 JZ C:062C
C:0x0684 40B8 JC C:063E
C:0x0686 E4 CLR A
C:0x0687 93 MOVC A,@A+DPTR
C:0x0688 A3 INC DPTR
C:0x0689 FA MOV R2,A
C:0x068A E4 CLR A
C:0x068B 93 MOVC A,@A+DPTR
C:0x068C A3 INC DPTR
C:0x068D F8 MOV R0,A
C:0x068E E4 CLR A
C:0x068F 93 MOVC A,@A+DPTR
C:0x0690 A3 INC DPTR
C:0x0691 C8 XCH A,R0
C:0x0692 C582 XCH A,DPL(0x82)
C:0x0694 C8 XCH A,R0
C:0x0695 CA XCH A,R2
C:0x0696 C583 XCH A,DPH(0x83)
C:0x0698 CA XCH A,R2
C:0x0699 F0 MOVX @DPTR,A
C:0x069A A3 INC DPTR
C:0x069B C8 XCH A,R0
C:0x069C C582 XCH A,DPL(0x82)
C:0x069E C8 XCH A,R0
C:0x069F CA XCH A,R2
C:0x06A0 C583 XCH A,DPH(0x83)
C:0x06A2 CA XCH A,R2
C:0x06A3 DFE9 DJNZ R7,C:068E
C:0x06A5 DEE7 DJNZ R6,C:068E
C:0x06A7 80BE SJMP C:0667........然后就跳到main了....
全局变量初始化代码就在这里面......
#11
你还记得用keil建工程的时候,有个提示:Copy Standard 8051 Startup Code to project folder and add file to project ?"
这个提示就是说,是否添加Startup code 到工程 ,Startup code 是cpu复位或上电启动后立即运行的一段启动代码。
c编程的时候cpu先找到Startup code 代码,在跳到main函数入口 所以不是从rom 0地址开始的
而Startup code 代码的作用是:
1:清除片内外RAM PDATA 堆栈和指针
2:如果有全局变量,则初始化,如果无全局变量,则直接进入main函数
这个提示就是说,是否添加Startup code 到工程 ,Startup code 是cpu复位或上电启动后立即运行的一段启动代码。
c编程的时候cpu先找到Startup code 代码,在跳到main函数入口 所以不是从rom 0地址开始的
而Startup code 代码的作用是:
1:清除片内外RAM PDATA 堆栈和指针
2:如果有全局变量,则初始化,如果无全局变量,则直接进入main函数
#12
其实选不选这个Startup code 程序都会自动加入Startup code 执行
#13
昨天已经找到了,谢谢大家了,
如Great_Bug所说,在startup.a51后面的那句 LJMP ?C_START是关键,而 C_START是在init.a51中定义的,init.a51主要就是全局变量的初始化,然后init.a51又调用了main函数。
在http://www.keil.com/support/man/docs/c51/c51_ap_startup.htm上有说明
Startup code is executed immediately upon reset of the target system. The Keil startup code performs (optionally) the following operations in order:
Clears internal data memory
Clears external data memory
Clears paged external data memory
Initializes the small model reentrant stack and pointer
Initializes the large model reentrant stack and pointer
Initializes the compact model reentrant stack and pointer
Initializes the 8051 hardware stack pointer
Transfers control to code that initializes global variables or to the main C function if there are no initialized global variables
如Great_Bug所说,在startup.a51后面的那句 LJMP ?C_START是关键,而 C_START是在init.a51中定义的,init.a51主要就是全局变量的初始化,然后init.a51又调用了main函数。
在http://www.keil.com/support/man/docs/c51/c51_ap_startup.htm上有说明
Startup code is executed immediately upon reset of the target system. The Keil startup code performs (optionally) the following operations in order:
Clears internal data memory
Clears external data memory
Clears paged external data memory
Initializes the small model reentrant stack and pointer
Initializes the large model reentrant stack and pointer
Initializes the compact model reentrant stack and pointer
Initializes the 8051 hardware stack pointer
Transfers control to code that initializes global variables or to the main C function if there are no initialized global variables
#14
STARTUP.A51,这个感觉像是“标准”51的初始化。根据你OPTION里选择的芯片和设备相关
而全局变量应该是编译,变量所在文件,进行链接的时候统一到main()前面进行初始化的
而全局变量应该是编译,变量所在文件,进行链接的时候统一到main()前面进行初始化的
#15
仔细读keil的相关文档,就会找到答案的。用一个编译器首先了解编译器。
#16
应该查看Keil编译器的代码
#17
弱弱的问一下,这里所说的初始化是指的把数据段从ROM搬到RAM吗?
#18
来迟了,呵呵,我是过来总结下大家的意思的:
startup.a51---》init.a51---》main()
初始化全局变量在init.a51中,,,
startup.a51---》init.a51---》main()
初始化全局变量在init.a51中,,,
#19
51平台下,全局变量初始化问题??
问题描述:
typedef xdata unsigned char xBYTE; //1字节
在文件test.c里这样定义并初始化一个全局数组:
static xBYTE uploadList_test[10] = {
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
};
然后在上电进入mian函数(main函数和test.c不是同一个文件)的时候调用test.c里的打印函数打印出变量uploadList_test的值,发现uploadList_test没有值。
51扩成了5个bank的,keil编译器中当把test.c放在comment区和bank4的时候用上述操作打出来是有值的,但是test.c放在bank0~bank3的时候打出来发现没有值!!!但是查看编译后的编译文件uploadList_test是已经有值了,是STARTUP.A51这个文件有问题吗??
问题补充:上述定义改成static code xBYTE uploadList_test[10]={........}直接从rom里面读数据打出来是有值的,但是改成 static const xBYTE uploadList_test[10]={........}打出来也没有值!!
这是怎么回事呢???
问题描述:
typedef xdata unsigned char xBYTE; //1字节
在文件test.c里这样定义并初始化一个全局数组:
static xBYTE uploadList_test[10] = {
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
};
然后在上电进入mian函数(main函数和test.c不是同一个文件)的时候调用test.c里的打印函数打印出变量uploadList_test的值,发现uploadList_test没有值。
51扩成了5个bank的,keil编译器中当把test.c放在comment区和bank4的时候用上述操作打出来是有值的,但是test.c放在bank0~bank3的时候打出来发现没有值!!!但是查看编译后的编译文件uploadList_test是已经有值了,是STARTUP.A51这个文件有问题吗??
问题补充:上述定义改成static code xBYTE uploadList_test[10]={........}直接从rom里面读数据打出来是有值的,但是改成 static const xBYTE uploadList_test[10]={........}打出来也没有值!!
这是怎么回事呢???
#20
#1
楼主的意思我没太看明白,暂时按照我的理解解释:
这个变量的初始化跟上电没关系, 编译完成后就完成了对全局变量的初始化,这个初始化的全局变量被放在数据段。单片机要做的只是顺着地址执行代码。并不是说 i的初始化写在代码的前面 烧录时就放在低地址处 ,这个变量的初始化由编译器完成,并把它放到数据段 ,你看不到它执行初始化的过程
这个变量的初始化跟上电没关系, 编译完成后就完成了对全局变量的初始化,这个初始化的全局变量被放在数据段。单片机要做的只是顺着地址执行代码。并不是说 i的初始化写在代码的前面 烧录时就放在低地址处 ,这个变量的初始化由编译器完成,并把它放到数据段 ,你看不到它执行初始化的过程
#2
;-------------------------------------------------------------------------
; STRUCTURE OF THE INITIALIZATION INFORMATION
; -------------------------------------------
; This section describes the initialization data generated by C51 for
; explicit variable initializations (in segment ?C_INITSEC).
;
; Explicit variable initilizations at C source level are stored by C51 in
; the segment ?C_INITSEC. All partial segments are combined at linker level
; to one segment. The segment end value DB 0 is taken from this library module
; INIT.A51.
;
; Structure of the ?C_INITSEC information:
; <Info> (see below) [BYTE] ----+ repeated
; <additional info> [BYTES depend on Info] ----+ repeated
; 0x00 [BYTE] <end of list mark>
;
; <Info> has the following format:
;
; Bit 7 6 5 4 3 2 1 0
; <Info> T T B L L L L L T=Type B=BIGBIT L=LENGTH
;
; If BIGBIT is set, another LENGTH BYTE FOLLOWS. The LENGHT
; info of the first byte is then the HIGH part.
;
; Typ is one of the following:
; 0 := IDATA init values; the following bytes follow:
; - 1 byte address
; - init data bytes according LENGTH specification
;
; 1 := XDATA init values; the following bytes follow:
; - 2 byte address (high byte first)
; - init data bytes according LENGTH specification
;
; 2 := PDATA init values; the following bytes follow:
; - 1 byte address
; - init data bytes according LENGTH specification
;
; 3, BIGBIT=0 := BIT init values; the followign bytes follow:
; - 1 byte for each bit according LENGTH specification
; this byte has the following format:
;
; Bit 7 6 5 4 3 2 1 0
; I B B B B B B B I := state of the bit
; B := bit address
;
; 3, BIGBIT=1 := HDATA init values; the following bytes follow:
; - another LENGTH byte (since BIGBIT is always 1)
; - 3 byte address (MSB first)
; - data bytes according LENGTH specification
;
;----------------------------------------------------------------------
; STRUCTURE OF THE INITIALIZATION INFORMATION
; -------------------------------------------
; This section describes the initialization data generated by C51 for
; explicit variable initializations (in segment ?C_INITSEC).
;
; Explicit variable initilizations at C source level are stored by C51 in
; the segment ?C_INITSEC. All partial segments are combined at linker level
; to one segment. The segment end value DB 0 is taken from this library module
; INIT.A51.
;
; Structure of the ?C_INITSEC information:
; <Info> (see below) [BYTE] ----+ repeated
; <additional info> [BYTES depend on Info] ----+ repeated
; 0x00 [BYTE] <end of list mark>
;
; <Info> has the following format:
;
; Bit 7 6 5 4 3 2 1 0
; <Info> T T B L L L L L T=Type B=BIGBIT L=LENGTH
;
; If BIGBIT is set, another LENGTH BYTE FOLLOWS. The LENGHT
; info of the first byte is then the HIGH part.
;
; Typ is one of the following:
; 0 := IDATA init values; the following bytes follow:
; - 1 byte address
; - init data bytes according LENGTH specification
;
; 1 := XDATA init values; the following bytes follow:
; - 2 byte address (high byte first)
; - init data bytes according LENGTH specification
;
; 2 := PDATA init values; the following bytes follow:
; - 1 byte address
; - init data bytes according LENGTH specification
;
; 3, BIGBIT=0 := BIT init values; the followign bytes follow:
; - 1 byte for each bit according LENGTH specification
; this byte has the following format:
;
; Bit 7 6 5 4 3 2 1 0
; I B B B B B B B I := state of the bit
; B := bit address
;
; 3, BIGBIT=1 := HDATA init values; the following bytes follow:
; - another LENGTH byte (since BIGBIT is always 1)
; - 3 byte address (MSB first)
; - data bytes according LENGTH specification
;
;----------------------------------------------------------------------
#3
51我用的不多,AVR常用,现在大部分编译器都会在Main之前插入一段代码,用于初始化,包括全局变量赋值等。编译完后,你Main函数对应的入口地址并不在程序存储器的0地址处,因为那里是初始化代码(其实还有一段中断向量跳转代码)
#4
代码都是烧写在ROM中的,而全局之类的变量都是在RAM中,所以上电的时候肯定要初始化的。我知道编译器肯定要在main之前加入初始化代码的,但是我不知道加在哪儿了?在keil 中debug后的汇编后的汇编中似乎看不见呢。
#5
这个文件我知道,我想知道的后编译后这段代码插在生成汇编代码的哪个地方了。
#6
有没有被优化掉?
#7
一般来说,全局变量如果有初始值,它们会被存放在ROM的某个区域,上电后会执行一段从ROM到RAM复制的过程.....这就是全局变量的初始化.
#8
很简单,汇编是从0地址开始,而c的main函数不是从0地址开始的
初始化在main之前,因为在main之前有启动代码和初始化代码
#9
支持8楼!
#10
在startup.a51的最后,有这么一句 LJMP ?C_START,单步过去....
C:0x0626 020664 LJMP C:0664
C:0x0664 90099D MOV DPTR,#0x099D
C:0x0667 E4 CLR A
C:0x0668 7E01 MOV R6,#0x01
C:0x066A 93 MOVC A,@A+DPTR
C:0x066B 60BC JZ C:0629
C:0x066D A3 INC DPTR
C:0x066E FF MOV R7,A
C:0x066F 543F ANL A,#vbatt(0x3F)
C:0x0671 30E509 JNB 0xE0.5,C:067D
C:0x0674 541F ANL A,#0x1F
C:0x0676 FE MOV R6,A
C:0x0677 E4 CLR A
C:0x0678 93 MOVC A,@A+DPTR
C:0x0679 A3 INC DPTR
C:0x067A 6001 JZ C:067D
C:0x067C 0E INC R6
C:0x067D CF XCH A,R7
C:0x067E 54C0 ANL A,#0xC0
C:0x0680 25E0 ADD A,ACC(0xE0)
C:0x0682 60A8 JZ C:062C
C:0x0684 40B8 JC C:063E
C:0x0686 E4 CLR A
C:0x0687 93 MOVC A,@A+DPTR
C:0x0688 A3 INC DPTR
C:0x0689 FA MOV R2,A
C:0x068A E4 CLR A
C:0x068B 93 MOVC A,@A+DPTR
C:0x068C A3 INC DPTR
C:0x068D F8 MOV R0,A
C:0x068E E4 CLR A
C:0x068F 93 MOVC A,@A+DPTR
C:0x0690 A3 INC DPTR
C:0x0691 C8 XCH A,R0
C:0x0692 C582 XCH A,DPL(0x82)
C:0x0694 C8 XCH A,R0
C:0x0695 CA XCH A,R2
C:0x0696 C583 XCH A,DPH(0x83)
C:0x0698 CA XCH A,R2
C:0x0699 F0 MOVX @DPTR,A
C:0x069A A3 INC DPTR
C:0x069B C8 XCH A,R0
C:0x069C C582 XCH A,DPL(0x82)
C:0x069E C8 XCH A,R0
C:0x069F CA XCH A,R2
C:0x06A0 C583 XCH A,DPH(0x83)
C:0x06A2 CA XCH A,R2
C:0x06A3 DFE9 DJNZ R7,C:068E
C:0x06A5 DEE7 DJNZ R6,C:068E
C:0x06A7 80BE SJMP C:0667........然后就跳到main了....
全局变量初始化代码就在这里面......
C:0x0626 020664 LJMP C:0664
C:0x0664 90099D MOV DPTR,#0x099D
C:0x0667 E4 CLR A
C:0x0668 7E01 MOV R6,#0x01
C:0x066A 93 MOVC A,@A+DPTR
C:0x066B 60BC JZ C:0629
C:0x066D A3 INC DPTR
C:0x066E FF MOV R7,A
C:0x066F 543F ANL A,#vbatt(0x3F)
C:0x0671 30E509 JNB 0xE0.5,C:067D
C:0x0674 541F ANL A,#0x1F
C:0x0676 FE MOV R6,A
C:0x0677 E4 CLR A
C:0x0678 93 MOVC A,@A+DPTR
C:0x0679 A3 INC DPTR
C:0x067A 6001 JZ C:067D
C:0x067C 0E INC R6
C:0x067D CF XCH A,R7
C:0x067E 54C0 ANL A,#0xC0
C:0x0680 25E0 ADD A,ACC(0xE0)
C:0x0682 60A8 JZ C:062C
C:0x0684 40B8 JC C:063E
C:0x0686 E4 CLR A
C:0x0687 93 MOVC A,@A+DPTR
C:0x0688 A3 INC DPTR
C:0x0689 FA MOV R2,A
C:0x068A E4 CLR A
C:0x068B 93 MOVC A,@A+DPTR
C:0x068C A3 INC DPTR
C:0x068D F8 MOV R0,A
C:0x068E E4 CLR A
C:0x068F 93 MOVC A,@A+DPTR
C:0x0690 A3 INC DPTR
C:0x0691 C8 XCH A,R0
C:0x0692 C582 XCH A,DPL(0x82)
C:0x0694 C8 XCH A,R0
C:0x0695 CA XCH A,R2
C:0x0696 C583 XCH A,DPH(0x83)
C:0x0698 CA XCH A,R2
C:0x0699 F0 MOVX @DPTR,A
C:0x069A A3 INC DPTR
C:0x069B C8 XCH A,R0
C:0x069C C582 XCH A,DPL(0x82)
C:0x069E C8 XCH A,R0
C:0x069F CA XCH A,R2
C:0x06A0 C583 XCH A,DPH(0x83)
C:0x06A2 CA XCH A,R2
C:0x06A3 DFE9 DJNZ R7,C:068E
C:0x06A5 DEE7 DJNZ R6,C:068E
C:0x06A7 80BE SJMP C:0667........然后就跳到main了....
全局变量初始化代码就在这里面......
#11
你还记得用keil建工程的时候,有个提示:Copy Standard 8051 Startup Code to project folder and add file to project ?"
这个提示就是说,是否添加Startup code 到工程 ,Startup code 是cpu复位或上电启动后立即运行的一段启动代码。
c编程的时候cpu先找到Startup code 代码,在跳到main函数入口 所以不是从rom 0地址开始的
而Startup code 代码的作用是:
1:清除片内外RAM PDATA 堆栈和指针
2:如果有全局变量,则初始化,如果无全局变量,则直接进入main函数
这个提示就是说,是否添加Startup code 到工程 ,Startup code 是cpu复位或上电启动后立即运行的一段启动代码。
c编程的时候cpu先找到Startup code 代码,在跳到main函数入口 所以不是从rom 0地址开始的
而Startup code 代码的作用是:
1:清除片内外RAM PDATA 堆栈和指针
2:如果有全局变量,则初始化,如果无全局变量,则直接进入main函数
#12
其实选不选这个Startup code 程序都会自动加入Startup code 执行
#13
昨天已经找到了,谢谢大家了,
如Great_Bug所说,在startup.a51后面的那句 LJMP ?C_START是关键,而 C_START是在init.a51中定义的,init.a51主要就是全局变量的初始化,然后init.a51又调用了main函数。
在http://www.keil.com/support/man/docs/c51/c51_ap_startup.htm上有说明
Startup code is executed immediately upon reset of the target system. The Keil startup code performs (optionally) the following operations in order:
Clears internal data memory
Clears external data memory
Clears paged external data memory
Initializes the small model reentrant stack and pointer
Initializes the large model reentrant stack and pointer
Initializes the compact model reentrant stack and pointer
Initializes the 8051 hardware stack pointer
Transfers control to code that initializes global variables or to the main C function if there are no initialized global variables
如Great_Bug所说,在startup.a51后面的那句 LJMP ?C_START是关键,而 C_START是在init.a51中定义的,init.a51主要就是全局变量的初始化,然后init.a51又调用了main函数。
在http://www.keil.com/support/man/docs/c51/c51_ap_startup.htm上有说明
Startup code is executed immediately upon reset of the target system. The Keil startup code performs (optionally) the following operations in order:
Clears internal data memory
Clears external data memory
Clears paged external data memory
Initializes the small model reentrant stack and pointer
Initializes the large model reentrant stack and pointer
Initializes the compact model reentrant stack and pointer
Initializes the 8051 hardware stack pointer
Transfers control to code that initializes global variables or to the main C function if there are no initialized global variables
#14
STARTUP.A51,这个感觉像是“标准”51的初始化。根据你OPTION里选择的芯片和设备相关
而全局变量应该是编译,变量所在文件,进行链接的时候统一到main()前面进行初始化的
而全局变量应该是编译,变量所在文件,进行链接的时候统一到main()前面进行初始化的
#15
仔细读keil的相关文档,就会找到答案的。用一个编译器首先了解编译器。
#16
应该查看Keil编译器的代码
#17
弱弱的问一下,这里所说的初始化是指的把数据段从ROM搬到RAM吗?
#18
来迟了,呵呵,我是过来总结下大家的意思的:
startup.a51---》init.a51---》main()
初始化全局变量在init.a51中,,,
startup.a51---》init.a51---》main()
初始化全局变量在init.a51中,,,
#19
51平台下,全局变量初始化问题??
问题描述:
typedef xdata unsigned char xBYTE; //1字节
在文件test.c里这样定义并初始化一个全局数组:
static xBYTE uploadList_test[10] = {
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
};
然后在上电进入mian函数(main函数和test.c不是同一个文件)的时候调用test.c里的打印函数打印出变量uploadList_test的值,发现uploadList_test没有值。
51扩成了5个bank的,keil编译器中当把test.c放在comment区和bank4的时候用上述操作打出来是有值的,但是test.c放在bank0~bank3的时候打出来发现没有值!!!但是查看编译后的编译文件uploadList_test是已经有值了,是STARTUP.A51这个文件有问题吗??
问题补充:上述定义改成static code xBYTE uploadList_test[10]={........}直接从rom里面读数据打出来是有值的,但是改成 static const xBYTE uploadList_test[10]={........}打出来也没有值!!
这是怎么回事呢???
问题描述:
typedef xdata unsigned char xBYTE; //1字节
在文件test.c里这样定义并初始化一个全局数组:
static xBYTE uploadList_test[10] = {
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
};
然后在上电进入mian函数(main函数和test.c不是同一个文件)的时候调用test.c里的打印函数打印出变量uploadList_test的值,发现uploadList_test没有值。
51扩成了5个bank的,keil编译器中当把test.c放在comment区和bank4的时候用上述操作打出来是有值的,但是test.c放在bank0~bank3的时候打出来发现没有值!!!但是查看编译后的编译文件uploadList_test是已经有值了,是STARTUP.A51这个文件有问题吗??
问题补充:上述定义改成static code xBYTE uploadList_test[10]={........}直接从rom里面读数据打出来是有值的,但是改成 static const xBYTE uploadList_test[10]={........}打出来也没有值!!
这是怎么回事呢???