一.伪指令
1.数据定义伪指令
DCB 字节分配
DCW/DCWU 半字(2字节)分配
DCD/DCDU 字(4字节)分配
DCQ/DCQU 8个字节分配
SPACE 分配一块连续的存储单元
(1)DCB
格式:标号 DCB 表达式
说明:分配一块字节单元,用表达式值初始化
表达式:使用双引号的字符串,或0~255的数字。
DCB可用“=”代替。
例:Array1 DCB 1,2,3,4,5 ;数组
str1 DCB "Your are welcome!" ;构造字符串并分配空间
(2)DCW/DCWU
例:Arrayw1 DCW 0xa,-0xb,0xc,-0xd
;构造固定数组,分配半字存储单元
(3)DCD/DCDU
例:Arrayd1 DCD 1334,234,245435 ;构造数组,并分配字存储单元
Label DCD Str1 ;该字单元存放str1的地址
(4)DCQ/DCQU
例:Arrayd1 DCQ 234234,98765541
;构造数组,分配字单元存储空间
;注:DCQ不能给字符串分配空间
(5)SPACE
格式:标号 SPACE 表达式
说明:分配一片连续的存储区域,初始化为0。
表达式:要分配的字节数
SPACE也可以用”%”代替
例:freespace SPACE 1000 ;分配1000字节的存储空间
2.ALIGN
格式:ALIGN [表达式[,偏移量]]
说明:通过填充字节,使当前的位置满足一定的对齐方式。
表达式:表达式的值为2的n次幂, 0≤n≤31,如1、2、4、8、16等,用于指定对齐方式。
没有表达式:默认,字对齐。
偏移量:数字表达式,自动对齐到“表达式值+偏移量”
例:
B START
ADD R0,R1,R2
DATA1 DCB "abcde"
ALIGN 4
START LDR R5,[R6]
3.AREA
格式: AREA 段名 属性,……
功能:定义段。
说明:如果段名以数字开头,那么该段名需用“|”字符括起来,如|7wolf|,用C的编译器产生的代码一般也用“|”括起来。
属性:表示该代码段/数据段的相关属性,多个属性用“,”分隔。
常见属性如下:
- DATA:定义数据段。
- CODE:定义代码段。
- READONLY:表示本段为只读。
- READWRITE:表示本段可读写。
- ALIGN=表达式,表达式的值为2的n次幂。
- COMMON属性:定义一个通用段,这个段不包含用户代码和数据。
注意:一个程序至少包含一个段,可以有多个数据段,多个代码段。
例:AREA test,CODE,READONLY
4.ENTRY
功能:指定汇编程序的入口
5.END
功能:告诉编译器源程序结束
6.EQU
格式:名称 EQU 表达式 [,类型]
功能:等值。
说明:将程序中的数字常量、标号、寄存器值等赋予一个等效的名称,这一点类似于C语言中的#define。
如果表达式为32位的常量,可以指定表达式的数据类型,类型域可以有以下3种:CODE16、CODE32、DATA。
可用“*”代替EQU。
例:
num1 EQU 1234 ;定义num1为1234
addr5 EQU str1+0x50
d1 EQU 0x2400,CODE32
;定义d1的为0x2400,
;且该处为32位的ARM指令
7.GET
格式:GET 文件名
说明:将一个源文件包含到当前的源文件中,并将被包含的源文件在当前位置展开进行汇编处理。
使用方法:在某源文件中定义一些宏指令,用MAP和FIELD定义结构化的数据类型,用EQU定义常量的符号名称,然后用GET将这个源文件包含到其他的源文件中。
使用方法与C语言中的“#include”相似。
GET只能用于包含源文件,包含其他文件则需要使用INCBIN伪指令。
例:
AREA mycode,DATA,READONLY
GET E:\code\prog1.s
;通知编译器在当前源文件
;包含源文件E:\code\ prog1.s
GET prog2.s
;通知编译器当前源文件包含
;可搜索目录下的prog2.s
...
END
8.INCBIN
格式:INCBIN 文件名
说明:将一个数据文件或者目标文件包含到当前的源文件中,编译时被包含的文件不作任何变动地存放在当前文件中,编译器从后面开始继续处理。
例:
AREA constdata,DATA,READONLY
INCBIN data1.dat
;源文件包含文件data1.dat
INCBIN E:\DATA\data2.bin
;源文件包含文件E:\DATA\data2.bin
...
END
9.IMPORT
略
10.EXPORT
略
11.ADR 小范围地址读取
格式:ADR{<cond>} <Rd>,<expr>
功能:基于PC相对偏移的地址值(expr 地址表达式)->Rd
例:
LOOP MOV R1,#OXF0
ADR R2,LOOP
;将LOOP的地址放入R2
12.ADRL 中等范围地址读取
格式:ADRL{<cond>} <Rd>,<expr>
功能:类似于ADR, 但比ADR读取更大范围的地址
例:
ADRL R0,DATA_BUF
ADRL R1,DATA_BUF+80
DATA_BUF
SPACE 100 ;定义100字节缓冲区
13.LDR 大范围地址读取
格式:LDR{<cond>} <Rd>,<=expr/label-expr>
说明:32位的立即数或一个地址值→Rd。
注:
(1)若加载的常数未超出MOV或MVN的范围,则使用MOV或MVN指令代替该LDR伪指令;否则汇编器将常量放入文字池(从PC到文字池的偏移量必须小于4 KB),并使用一条程序相对偏移的LDR指令从文字池读出常量。
(2)与ARM指令的LDR相比,伪指令的LDR的参数有”=”符号。
例:
LDR R0,=0x12345678 ;加载32位立即数0x12345678
LDR R0,=DATA_BUF+60 ;加载DATA_BUF地址+60
...
LTORG ;声明文字池
...
14.NOP空操作
功能:不产生任何有意义的操作,只是占用一个机器时间
注:NOP在汇编时将会被替代成ARM中的空操作,比如可能为”MOV R0,R0″指令等。
二.汇编语言语句格式

三.汇编程序设计示例
1.基本结构
AREA example,CODE,READONLY ;定义代码段为example
CODE32
ENTRY ;程序入口
Start
MOV R0, #40 ;R0=40
MOV R1, #16 ;R1=16
ADD R2, R0, R1 ;R2= R0 +R1
MOV R0, #0x18 ;传送到软件中断的参数
LDR R1, =0x20026 ;传送到软件中断的参数
SWI 0x123456 ;通过软件中断指令返回
END ;文件结束
2.子程序调用
AREA Init,CODE,READONLY ;定义一个代码段
ENTRY ;定义一个程序入口
LOOP1
MOV R0, #211 ;给参数R0赋值211
MOV R1, #106 ;给参数R1赋值106
MOV R2, #64 ;给参数R2赋值64
MOV R3, #5 ;给参数R3赋值5
BL SUB1
;调用子程序SUB1
;同时将子程序的返回地址存放在链接寄存器R14(LR)中
MOV R0, #0x18 ;传送到软件中断的参数
LDR R1, = 0x20026 ;传送到软件中断的参数
SWI 0x123456 ;通过软件中断指令返回
SUB1
SUB R0, R0, R1 ;子程序代码
SUB R0, R0, R2
SUB R0, R0, R3
MOV PC, LR ;从子程序返回
END
3.条件执行举例
C语言代码:
int gcd(int a,int b)
{
while(a!=b){
if(a>b)
a=a-b;
else
b=b-a;
}
return a;
}
ARM代码段:
R0=a,R1=b
gcd
CMP R1,R1 ;比较a和b大小
SUBGT R0,R0,R1 ;if (a>b) a=a-b (if a==b do nothing)
SUBLT R1,R1,R0 ;if (b>a) b=b-a (if a==b do nothing)
BNE gcd ;if (a!=b) then 跳转到gcd处继续执行
MOV PC,LR ;子程序结束,返回
c语言代码:
if(a==0 || b==1)
c=d+e;
ARM代码段:
CMP R0,#0 ;判断是否等于0
CMPNE R1,#1 ;如果R0不等于0,判断R1是否等于1
ADDEQ R2,R3,R4 ;R0=0或R1=1时,R2=R3+R4
4.循环语句
MOV R0,#loopcount
loop
...
SUBS R0,R0,#1
BNE loop
四.在C/C++程序中内嵌汇编指令的语法格式
在ARM的C语言程序中可以使用关键字__asm来加入一段汇编语言的程序。
__asm
{
instruction/*comment*/
...
}
示例:
#include <stdio.h>
void my_strcpy (const char *src, char *dest) //声明一个函数
{
char ch; //声明一个字符型变量。
__asm //调用关键词__asm。
{
LOOP //循环入口。
LDRB ch,[src],#1 // ARM指令,ch←[src], src ←src +1。
STRB ch,[dest],#1 // ARM指令, [dest]←ch,[dest]←[dest]+1。
CMP ch,#0 // 比较ch是否为零,判断字符串是否结束。
BNE LOOP // NE为不相等条件, ch是否为零,否则循环。
}
}
Comment