关于初始化C程序运行环境的疑问
有一个实验,使用了汇编语言程序写的一个启动文件Startup.S ,其作用是初始化C程序的运行环境,然后进入C语言MAIN程序代码。它的功能是很清楚的,就是完成RW、ZI段在运行域中的搬运过程,理解没有问题。但是弱弱地问一下:如果mian程序是汇编语言程序,我想也应该存在加载域和运行域的问题,即同样存在初始化运行环境的问题(从ROM搬运一些代码到指定的RAM中)。为什么程序是用汇编语言写的程序时就不存在这个问题了?即不需要Startup.S。 有些模糊,请指点为盼! Startup.S其实就是相当于bootloader的作用,创建C语言运行的环境,不只是搬运RW、ZI,还有初始化堆栈,初始化PLL等作用,汇编语言好处是可以可以指定好入口地址,每条语句都被准确无误地翻译为机器码,不会多不会少可以指定长度,如果你定义了变量,变量也要给出实际的地址,不像C由编译器决定,由运行环境初始化,所以开机的引导代码肯定是汇编的啦 非常感谢国旭的答复!!!我说的这个Startup.S就只是搬运的任务,我贴在下面,请你看看。我的问题是:汇编语言程序也应该存在运行域和加载域的问题,那么它的搬运工作是由谁完成的?难道汇编语言程序只要用ADS1.2中的ARM Linker 指定一下RO_Base RW_Base,就可以完成加载域和运行域的搬运工作了?这个工作是由编译器完成的还是ADS1.2工程模板完成的?望指点为盼!!!再次谢谢啦!; 起动文件。初始化C程序的运行环境,然后进入C程序代码。(C Main就不贴了)
IMPORT |Image$$RO$$Limit|
IMPORT |Image$$RW$$Base|
IMPORT |Image$$ZI$$Base|
IMPORT |Image$$ZI$$Limit|
IMPORT Main ; 声明C程序中的Main()函数
AREA Start,CODE,READONLY ; 声明代码段Start
ENTRY ; 标识程序入口
CODE32 ; 声明32位ARM指令
Reset LDR SP,=0x40003F00
; 初始化C程序的运行环境
LDR R0,=|Image$$RO$$Limit|
LDR R1,=|Image$$RW$$Base|
LDR R3,=|Image$$ZI$$Base|
CMP R0,R1
BEQ LOOP1
LOOP0 CMP R1,R3
LDRCC R2,,#4
STRCC R2,,#4
BCC LOOP0
LOOP1 LDR R1,=|Image$$ZI$$Limit|
MOV R2,#0
LOOP2 CMP R3,R1
STRCC R2,,#4
BCC LOOP2
B Main ; 跳转到C程序代码Main()函数
END 这里有一篇关于RO、RW、ZI段的解析文章
点击此处下载 ourdev_610910VF512G.txt(文件大小:35K) (原文件名:关于ARM中程序的zi,rw,ro段的解析.txt)
我觉得汇编引导部分没有RW,ZI段,只有RO段,事实也是如此,程序里面也没有用到可写的全局变量吧,所以对它来说,只要入口点对准复位向量,就可以运行,只要把RO段烧写进去,开机就能运行 非常感谢你的指点! 你说的“汇编引导部分没有RW,ZI段,只有RO段”,应该是这样,但是汇编语言程序不光只是汇编引导部分,也有其他功能的汇编语言程序。这样的汇编语言程序也应该存在运行域和加载域的问题,难道不存在吗?有些糊涂。望继续得到你的指点! 非常感谢国旭的指点!“了解RO,RW和ZI”这篇文章我看过的。写的挺好。但是我问的问题是:难道汇编语言程序(并非引导部分)就不存在运行域和加载域的问题?望再给予指导!!!先谢谢啦!!! 回复【5楼】JYN0000
-----------------------------------------------------------------------
由于用的是汇编,编译系统不会提供任何辅助的函数/功能,所有都需要自己去实现。
因此,存在什么,不存在什么,完全取决于汇编程序设计。需要某功能,那么就实现,于是它具有;反之则什么都没。 谢谢dr2001的指点!!! 我想一个汇编语言程序也是需要加载域和运行域的,做一些简单的汇编语言程序实验时,就没有上面给出的Startup.S文件即没有看到RW、ZI段往运行域中的搬运过程。所以就不明白这一点.难道是ADS1.2中的编译器帮我们完成了RW和ZI的搬运工作?(因为使用了ADS1.2提供的ARM Executable Image工程模板) 1、汇编需要就自己实现。汇编器和链接器在汇编层面上提供的功能是有限的。
对ARM来说,主要是LDR Reg,=xxx这样的伪指令相关的支持是比别的汇编器多出来的功能。
2、对ARM的RVCT编译系统来说,数据搬运是C语言运行库初始化工作的一部分。RW的移动;ZI的清零,都在C运行库初始化时自动完成。
具体该操作由谁实现,对应于S文件调用的是__main,还是main,还是其它。。。
具体参考编译器手册,裁剪C运行库的章节吧。 经过几天对前后十几个实验的比较、查资料、网友的指点,终于有些明白了:周立功公司提供的基础实验中,2.6以前的程序都是一些简单的汇编语言程序,没有牵扯到中断向量初始化、堆栈指针初始化...的问题,所以Make后看它们的Imagecomponentsizes,RO Datd、RWDatd、ZIData均等于0,所以就不需要RW、ZI段往运行域中的搬运过程。但是2.7中就有了InitStack,它就是堆栈指针的初始化过程,就属于启动程序的一部分,所以看它的Make后的Imagecomponentsizes:RO Datd=0, RWDatd=0, ZIData=576,也就是说,它是需要搬运的。但是该实验没有像实验2.8那样的Startup.S,所以虽有576B的ZI段,应该清零却没有被清零。有实验图片验证,但是不会贴图,望谅解!并欢迎大家一起讨论! 回复【1楼】xu.sunrise 国旭
-----------------------------------------------------------------------
你好,我想问下在调试以下这个程序时会出现这样的
L6218E:Undefined symbol Image $$ R0 $$ Limit(referred from Startup.o)
L6218E:Undefined symbol Image $$ RW $$ Base(referred from Startup.o)
L6218E:Undefined symbol Image $$ ZI $$ Base(referred from Startup.o)
L6218E:Undefined symbol Image $$ ZI $$ Limit(referred from Startup.o)
错误提示,能告诉我为什么吗,怎么修改,谢谢
IMPORT |Image$$RO$$Limit|
IMPORT |Image$$RW$$Base|
IMPORT |Image$$ZI$$Base|
IMPORT |Image$$ZI$$Limit|
IMPORT Main ; 声明C程序中的Main()函数
AREA Start,CODE,READONLY ; 声明代码段Start
ENTRY ; 标识程序入口
CODE32 ; 声明32位ARM指令
Reset LDR SP,=0x40003F00
; 初始化C程序的运行环境
LDR R0,=|Image$$RO$$Limit|
LDR R1,=|Image$$RW$$Base|
LDR R3,=|Image$$ZI$$Base|
CMP R0,R1
BEQ LOOP1
LOOP0 CMP R1,R3
LDRCC R2,,#4
STRCC R2,,#4
BCC LOOP0
LOOP1 LDR R1,=|Image$$ZI$$Limit|
MOV R2,#0
LOOP2 CMP R3,R1
STRCC R2,,#4
BCC LOOP2
B Main ; 跳转到C程序代码Main()函数
END
页:
[1]