ARM汇编程序设计及一些格式要求说明
一般地,ARM源程序文件名的后缀名如下:
汇编文件: *.S
引入文件: *.INC
C程序 : *.c
头文件 : *.h
汇编语句格式:
[ 标号 ] <指令 | 条件 | S > <操作数> [ ;注释]
1、所有标号必须在一行的顶格书写,其后面不要加:
2、所有指令均不能顶格书写
3、ARM汇编器对标识符大小写敏感,书写标号及指令时字母大小要一致,在ARM汇编程序中,一个ARM指令,伪指令,寄存器名可以全部为大写字母,也可以全部为小写字母,但不要大小写混合使用
4、注释使用 ;或者 @,@表示开始到此行结束,注释可以在一行顶格书写(对ADS汇编格式,只支持 ; )
5、源程序中允许空行
6、如果单行太长,可以使用字符 / 将其分行, / 后不能有任何字符,包括空格
7、对于变量的设置,常量的定义,其标识符必须在一行的顶格书写
标号:在ARM汇编中,标号代表一个地址,根据标号生成方式,可以分为以下3种
1、基于PC的标号,例如: BL LEDTEST
2、基于寄存器的标号,例如: MAP 0x00,R9
3、绝对地址,例如: LDR R0,=WTCON
局部标号:主要用于局部范围代码中,对宏定义也非常有用,格式如下:
N { routname }
N是局部标号,为 0 ~ 99
routname是局部标号作用范围的名称
局部标号引用格式: % {F | B } {A | T} N {routname }
其中:
% 表示局部标号引用操作
F 指示编译器只向前搜索
B 指示编译器只向后搜索
A 指示编译器搜索宏的所有嵌套层次
T 指示编译器搜索宏的当前层
应用举例如下:
mov r1, #16
0 subs r1,r1, #1
bne %B0
宏定义及其作用:使用宏定义可以提高程序的可读性,简化程序代码和同步修改,宏首先要定义,然后再使用,当源程序被汇编时,汇编器将展开每一个宏调用,用宏定义体代表程序中的宏调用,并使用实际的参数值代替宏定义时的形式参数
宏定义应用举例如下:
.....
MACRO ;宏定义
CALL $FUNCTION , $DAT1 , $DAT2 ;宏名称为CALL,带有3个参数
IMPORT $FUNCTION ; 声明外部子程序
MOV R0, $DAT1 ; 设置子程序参数,R0 = $DAT1
MOV R1, $DAT2 ;
BL FUNCTION ; 调用子程序
MEND ; 宏定义结束
......
汇编预处理后,宏调用将被展开,程序清单如下:
......
IMPORT FADD1
MOV R0, #3
MOV R1, #3
BL FADD1
子程序的调用:使用BL指令进行调用,该指令会把返回的PC值保存在LR
示例如下:
......
BL DELAY
......
DELAY ....
MOV PC,LR
当子程序指令完毕后,使用 MOV, B/BX , STMFD 等指令返回,STMFD 要与 LDMFD配套使用
STMFD SP! , {R0-R7, LR}
......
LDMFD SP! , {R0-R7,PC }
ARM7TDMI (-S) 是没有BLX指令的,但可以通过以下几条程序实现其功能
ADR R1 , DELAY+1
MOV LR , PC ; 保存