1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150 | ARM 汇编语言 例子
;-------常见指令后缀
EQ ;相等
NE ;不相等
CS/HS ;无符号数大于或等于
......
ADD R0,R0,#1 ; R0+1 -> R0
MOV R0,#0X00FF ; R0=0X00FF
MOVS R0,R1,LSL #3 ;将寄存器R1值 左移3位后传送到R0 并影响标志位
MVN R0,R1 ;将寄存器R1值按位求反后送入R0
MVN R0,#0XFF ;将立即数0XFF 按位取反后装入R0 然后R0=0xffffff00
ADD R0,R1,R2 ; R1+R2 ->R0
MOV R0,R1 ; R1->R0
LDR R0,[R1] ; [R1]->R0 假设 R1存储的是0x3FE是内存地址 则是将00X3FE内存地址中的数据存入R0
MOV R0,R1,LSL #2 ; R1<<2 ->R0, LSL 左移命令 LSR右移命令 ASR算数右移 ROR循环右移 RRX带扩展的循环右移
ADD R0,R1,R2,LSR #3 ;R1 + R2>>3 ->R0
SUB R0,R0,#1 ; R0=R0-1
SUB R0,R1,R2 ; R0=R1-R2
SUB R0,R1,R2,LSL #3 ;R0=R1-(R2<<3)
LDR R0,[R1,#2] ; [R1+2] ->R0 R1中的值+2 当作内存地址 然后将内存地址中的值 赋值到R0
STR R1,[R0,#0X12] ; R1 ->R0+0X12地址内存中去
STR R1,[R0],#0X12 ; R1 ->R0+0X12地址内存中去 R0=R0+0X12
RSB R0,R0,#0XFFFF ;R0=0XFFFF - R0
RSB R0,R1,R2 ;R0=R2-R1
AND R0,R1,R2 ; R0= R1 & R2
AND R0,R0,#3 ; R0=R0&3
ORR R0,R0,#3 ; R0=R0|3
EOR R0,R0,#0F ; R0=R0 异或 0F
BIC R0,R0,#0F ; 将R0的低4位 清0
CMP R1,R0 ; R1-R0 并改变CPSR的标志位
CMN R1,R0 ; R1+R0 并改变CPSR的标志位
CMN R1,#0x200 ; 将R1值和立即数0X200相加 并根据结果改变CPSR标志位
TST R1,#0XF ; 检测R1的低4位是否为0
TEQ R1,R2 ; 将R1的值 和R2的值 进行异或运算 然后改变CPSR的标志位
;程序状态寄存器处理指令
MRS R0,CPSR ;将CPSR->R0
ORR R0,R0,#C0 ;R0=R0|C0 ,即屏蔽外部中断 和快速外部中断
MSR CPSR,R0 ;R0->CPSR
;多寄存器寻址
;从左赋值到右 用于存储器读取数据 比单字读取操作方便
;IA:每次传送后地址加4
;IB:每次传送前地址加4
;DA:每次传送后地址减4
;DB:每次传送前地址减4
;FD:满递减堆栈
;ED:空递减堆栈
;FA:满递增堆栈
;EA:空递增堆栈
LDMIA R0!,{ R1-R3,R5} ; [R0] ->R1 假设R0=0XF1 将内存地址0XF1中的数据赋值到 R1
; [R0+4] ->R2 R0=0XF1+4 将内存地址0XF1+4 中的数据赋值到R2
; [R0+8] ->R3
; [R0+12] ->R5
STMIA R1!,{R3-R9} ;将R3~R9 数据存储到R1 R1更新值
;R3->[R1]
;R4->[R1+4]
;R5->[R1+8]
;R6->[R1+12]
SWP R1,R1,[R0] ;将R1的内容和R0指向的存储单元内容进行交换
;异常产生指令
SWI 0x02 ;软中断 调用操作系统编号为0X02的系统例程
BKPT 0XFF32 ;
;堆栈寻址 栈会向上增长 递增堆栈,也会向下增长 递减堆栈
;后缀 IB 先增加堆栈地址值 SP+4,然后再出栈 入栈 SP->XX
;后缀 IA 先完成操作在增加地址 SP->XX SP+4
;后缀 DB 先减少堆栈地址值 SP-4,然后再出栈 入栈 SP->XX
;后缀 DA 先完成操作在减少地址值 SP->XX SP-4
STMFD SP!,{R1-R3,LR} ; 将寄存器R1~R3 LR 入栈,满递减堆栈 R1->SP SP++ R2->SP SP++....
LDMFD SP!,{R1-R3,LR} ; 将栈中数据 出栈 存入R1~R3 LR,SP->R1 SP--, SP->R2 SP--
;跳转指令
LDR PC,[PC,#+0X00FF] ; [PC+8+0X00FF] ->PC 修改程序指针 PC值 实现跳转
B task1 ;无条件 跳转到task1处执行
B 0x1234 ;跳转到绝对地址 0X1234处
BL task1 ;先将当前执行指令的下一条指令的地址值 存储到链接寄存器R14(LR)中(以便再返回来) 在跳转到task1标号执行
BLX task1 ;先将当前执行指令的下一条指令的地址值 存储到链接寄存器R14(LR)中(以便再返回来) 并从ARM状态切换到Thumb状态 在跳转到task1标号执行
BLX R0 ;先将当前执行指令的下一条指令的地址值 存储到链接寄存器R14(LR)中(以便再返回来) 并从ARM状态切换到Thumb状态 在跳转到R0中的地址处执行
BX R0 ; 跳转到R0处执行 如果R0[0]=1 则切换到Thumb状态
;ARM 常见伪指令
DCB ;分配一段字节的内存单元 并用指定的数据初始化
DCD DCDU ;分配一段字的内存单元 ,并用指定的数据初始化
DCQ DCQU ;分配一段双字的内存单元 并用64位整型数据初始化
DCW DCWU ;分配一段半字的内存单元 并用指定的数据初始化
ALIGN ; 边界对齐
AREA ; data段 rom段定义
END ; 汇编结束
ENTRY ; 程序入口
EQU ;常量定义 类似C宏定义
EXPORT , GLORBAL ;声明一个符号可以被 其他文件引用
IMPORT EXYERN ;声明一个外部符号
NOP ; 延时空操作
;---------ARM asm Example -------
AREA BUF,DATA,READWRITE ;声明一个数据段 BUF in RAM , BUF 可读可写
count DCB 30 ; 定义一个字节单元count
AREA EXAMPLE1 ,CODE,READONLY ; 声明代码段 EXAMPLE1 in ROM , 只读
ENTRY ; 程序入口
CODE32 ;声明32位ARM指令
START
LDRB R0,count ;R0=count
MOV R1,#10 ;R1=0X10
ADD R0,R0,R1 ;R0=R0+R1
B START ;跳转到START处执行
END ;程序结束
|