熟悉了ARM体系结构和常用的汇编指令,我们就可以尝试编写简单的ARM汇编程序了,在一段完整的汇编程序中,不仅包含了各种汇编指令和伪指令,还包含了各种伪操作。伪操作可以让程序员更加方便的编写汇编程序,实现更加复杂的逻辑功能。
3.5.1?ARM汇编程序格式
????ARM汇编程序是以段为单位进行组织的,在一个汇编文件中,可以有不同的section,?分为代码段,数据段等,各个段之间相互独立,一个ARM汇编程序至少要有一个代码段。我们可以使用AREA伪操作来标识一个段的起始,段名和段的读写属性。
????AREA?COPY,CODE,READONLY;?当前段属性为代码段,只读,段名为copy
????????ENTRY
????START
????????LDR?R0,=SRC
????????LDR?R1=DST
????????MOV?R2,?#10
????LOOP?
????????LDR?R3,?[R0],?#4
????????STR?R3,?[R1],?#4
????????SUBS?R2,?R2,?#1
????????BNE?LOOP
?AREA?COPYDATA,?DATA,?READWRITE
SRC?DCD?1,2,3,4,5,6,7,8,9
DST?DCD?0,0,0,0,0,0,0,0,0,
END
上面的汇编代码实现了数据块的复制功能。该汇编程序由两个程序段组成;一个代码段,一个数据段,两个段相互独立。由AREA伪操作来标识一个段的起始,段名,段属性(CODE,?DATA)?和读写权限(READONLY,?READWRITE)
????C程序一般都是从main?函数开始执行的,那汇编程序从哪里开始执行的呢?ARM汇编程序从ENTRY这个伪操作来表示汇编程序的运行入口,使用伪操作END来标识汇编程序的结束。
????在ARM汇编程序中可以使用标号,像C语言一样,在汇编语言中,标号代表的指令地址,如上述代码中的LOOP标号,和BNE指令结合使用可以构建一个循环程序结构。
????在C程序中,我们可以使用//或者/**/?来注释代码,在汇编程序中,我们同样也可以添加注释,我们使用分号,来注释代码,在一个空行的行首或者一条指令语句的末尾添加一个分号,然后就可以在分号后面添加注释。以增加程序的可读性。
?3.5.2?符号与标号
????在ARM汇编中,我们可以使用符号来标识一个地址,变量或者数字常量。当用符号来标识一个地址的时候,这个符号通常被称作标号。
??符号的命名规则和C鱼宴的标识符命名规则一样,字母和数字以及下划线组成,符号的开头不能使用数字。
????符号的命名在其作用域内必须唯一,不能与系统内部或者系统预定的符号同名,不能与指令助记符同名,一般情况下,一个符号的作用域是整个汇编源文件,有时候我们会直接通过数字[0,99]而不是使用字符来进行地址引用。
%{F|B|A|T}?N{routename}
???在局部标号的饮用格式中,由大括号{}括起来的部分是可选项,N表示局部标号,其余的参数说明如下。
%?引用符号,对一个局部标号产生引用
F?表示编译器只向前搜索
B?表示后向搜索
A?指示编译器搜索宏的所有宏命令层
T?指示编译器搜索宏的当前层
N?局部标号名字。
routename?局部标号作用范围名称,使用ROUT定义。
若B,F没有指定,编译器将默认先向后搜索,然后向前搜索,若A,T都没有指定,则汇编程序默认搜索从当前层到到最顶层所有宏命令,但是不搜索较低层宏命令。如果在标签中或者对一个标签的引用中制定了Routename,?则汇编程序将其与最近的一个前ROUT指令的名称进行比较,如果不匹配,则汇编程序会生成一条错误消息,汇编失败。
??在汇编代码中,使用局部标号的示例程序如下。
?AREA?COPY,CODE,READONLY;?当前段属性为代码段,只读,段名为copy
????????ENTRY
????START
????????LDR?R0,=SRC
????????LDR?R1=DST
????????MOV?R2,?#10
????0?
????????LDR?R3,?[R0],?#4
????????STR?R3,?[R1],?#4
????????SUBS?R2,?R2,?#1
????????BNE?%B0;跳到前面局部标号0处,构成循环
?AREA?COPYDATA,?DATA,?READWRITE
SRC?DCD?1,2,3,4,5,6,7,8,9
DST?DCD?0,0,0,0,0,0,0,0,0,
END