JYN0000 发表于 2011-1-12 20:49:18

关于初始化C程序运行环境的疑问

有一个实验,使用了汇编语言程序写的一个启动文件Startup.S ,其作用是初始化C程序的运行环境,然后进入C语言MAIN程序代码。它的功能是很清楚的,就是完成RW、ZI段在运行域中的搬运过程,理解没有问题。但是弱弱地问一下:如果mian程序是汇编语言程序,我想也应该存在加载域和运行域的问题,即同样存在初始化运行环境的问题(从ROM搬运一些代码到指定的RAM中)。为什么程序是用汇编语言写的程序时就不存在这个问题了?即不需要Startup.S。 有些模糊,请指点为盼!

xu.sunrise 发表于 2011-1-12 23:30:12

Startup.S其实就是相当于bootloader的作用,创建C语言运行的环境,不只是搬运RW、ZI,还有初始化堆栈,初始化PLL等作用,汇编语言好处是可以可以指定好入口地址,每条语句都被准确无误地翻译为机器码,不会多不会少可以指定长度,如果你定义了变量,变量也要给出实际的地址,不像C由编译器决定,由运行环境初始化,所以开机的引导代码肯定是汇编的啦

JYN0000 发表于 2011-1-13 09:10:57

非常感谢国旭的答复!!!我说的这个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

xu.sunrise 发表于 2011-1-13 12:36:22

这里有一篇关于RO、RW、ZI段的解析文章
点击此处下载 ourdev_610910VF512G.txt(文件大小:35K) (原文件名:关于ARM中程序的zi,rw,ro段的解析.txt)
我觉得汇编引导部分没有RW,ZI段,只有RO段,事实也是如此,程序里面也没有用到可写的全局变量吧,所以对它来说,只要入口点对准复位向量,就可以运行,只要把RO段烧写进去,开机就能运行

JYN0000 发表于 2011-1-14 14:24:50

非常感谢你的指点! 你说的“汇编引导部分没有RW,ZI段,只有RO段”,应该是这样,但是汇编语言程序不光只是汇编引导部分,也有其他功能的汇编语言程序。这样的汇编语言程序也应该存在运行域和加载域的问题,难道不存在吗?有些糊涂。望继续得到你的指点!

JYN0000 发表于 2011-1-14 14:41:07

非常感谢国旭的指点!“了解RO,RW和ZI”这篇文章我看过的。写的挺好。但是我问的问题是:难道汇编语言程序(并非引导部分)就不存在运行域和加载域的问题?望再给予指导!!!先谢谢啦!!!

dr2001 发表于 2011-1-14 14:46:55

回复【5楼】JYN0000
-----------------------------------------------------------------------

由于用的是汇编,编译系统不会提供任何辅助的函数/功能,所有都需要自己去实现。

因此,存在什么,不存在什么,完全取决于汇编程序设计。需要某功能,那么就实现,于是它具有;反之则什么都没。

JYN0000 发表于 2011-1-14 16:14:00

谢谢dr2001的指点!!! 我想一个汇编语言程序也是需要加载域和运行域的,做一些简单的汇编语言程序实验时,就没有上面给出的Startup.S文件即没有看到RW、ZI段往运行域中的搬运过程。所以就不明白这一点.难道是ADS1.2中的编译器帮我们完成了RW和ZI的搬运工作?(因为使用了ADS1.2提供的ARM Executable Image工程模板)

dr2001 发表于 2011-1-16 15:49:53

1、汇编需要就自己实现。汇编器和链接器在汇编层面上提供的功能是有限的。
   对ARM来说,主要是LDR Reg,=xxx这样的伪指令相关的支持是比别的汇编器多出来的功能。

2、对ARM的RVCT编译系统来说,数据搬运是C语言运行库初始化工作的一部分。RW的移动;ZI的清零,都在C运行库初始化时自动完成。
   具体该操作由谁实现,对应于S文件调用的是__main,还是main,还是其它。。。
   具体参考编译器手册,裁剪C运行库的章节吧。

JYN0000 发表于 2011-1-18 16:59:04

经过几天对前后十几个实验的比较、查资料、网友的指点,终于有些明白了:周立功公司提供的基础实验中,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段,应该清零却没有被清零。有实验图片验证,但是不会贴图,望谅解!并欢迎大家一起讨论!

0607020063 发表于 2011-5-27 11:28:34

回复【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]
查看完整版本: 关于初始化C程序运行环境的疑问