AM335x学习心得之读懂启动文件
在以前学习ARM的时候,经常要用到启动文件,虽然AM335X的学习过程中,用不到再学习这些启动文件,而且这些文件都是用C语言编写,用不着大家在用汇编写,但是在代码中也会看到一些用大写的汇编代码,如果读懂他们,也就读懂了启动了文件,例举一些经常用到了汇编代码,对理解启动代码很有帮助。
1. REQUIRE8和PRESERVE8 在定义堆栈的时候,我们经常会看到REQUIRE8和PRESERVE8伪指令,这两个指令是告诉编译器保证8字节对齐。因为ARM的编译器默认是4字节对齐的,而在堆栈的操作中很多时候我们会用到LDRD和STRD这样的双字传送指令,所以这里的存储器就要求要8字节对齐。 实际操作中,REQUIRE8和PRESERVE8并不会直接完成对齐的操作,而只是更改编译器中的编译属性,真正的对齐操作是由ALIGN来完成的。 2. AREA AREA 伪指令用来定义一个存储器的区域,一般我们把它叫做段(sector).其语法格式如下: AREA 段名称 属性1,属性2, …… 需要注意的是如果段名称是由数字或者特殊字符开头,则需要用||把段名称括起来。例如 |3_Code| 或者|.code| 属性部分用来表示该存储器段的相关属性,多个属性之间用逗号隔开,常用的属性如下: - NOINIT : 非初始化 - CODE :用于定义代码段,定义了该属性则默认READONLY属性 - DATA : 用于定义数据段,定义了该属性则默认READWRITE属性 - READWRITE/READONLY : 用来标示本段是只读还是可读可写 - ALIGN : 存储器的访问的对齐, 一般定义为ALIGN = N,其中N表示对齐的字数,例如: ALIGN = 2表示对齐方式是2的2次方,即4字节对齐 ALIGN = 3 标示对齐方式是2的3次方, 即8字节对齐 - COMMON : 该属性用来定义一个通用的存储区,不包含任何代码和数据。在不同源文件中定义的COMMON区域共享一个存储区域。 3. THUMB(CODE16)、ARM(CODE32) 这两个伪指令通知编译器,其后的指令为16位的Thumb指令还是32位的ARM指令。由于ARM7的内核支持这两种指令模式,而且允许在同一个代码中,对这两个模式进行切换,所以在使用ARM和Thumb指令混合编程的代码中,用这两条伪指令来切换。 4. EXPORT,IMPORT,EXTERN 这两个伪指令用来声明或引用一个全局的变量(函数)标号。在汇编和C的混合编程代码中,可以通过这两个伪指令来传递变量(函数)标号。其中EXPORT也可以用GLOBAL代替。 需要注意的是虽然汇编语言不区分大小写,但变量(函数)的标号是区分大小写的。 IMPORT的用法和EXTERN类似。它们主要的区别在于如果外部文件未定义本标号,是否添加到本源文件的符号表中,对一般的程序员来讲不用关心这个差别。 如果在EXPORT和IMPORT后面有[WEAK]的参数,表明本指令声明的标号如果在其他地方遇到同名的标号,本标号的优先级最低。 5. SPACE SPACE用来保留一个指定大小的存储空间。该语句比较简单,例如: SPACE 100 表示在本指令开始的地址划分出一个100字节大小的空间。 6、END END伪指令用来通知编译器到了源程序的结尾。他和ENTRY相对应,一个应用程序只应该有一个END。
7、GET, INCLUDE GET和INCLUDE类似,它们用于将一个源文件包含到当前的源文件中,并将被包含的源文件在当前位置进行汇编处理。这个和C语言中的”#include”类似 8、 ENTRY ENTRY用于指定汇编程序的入口点,有点像C语言中的main函数。一个完整的汇编应用程序至少需要一个ENTRY。
|