一 ARM寄存器
1.通用寄存器
1).未分组寄存器:R0~R7R15:程序计数器(PC):用于控制程序中指令的执行顺序。正常运行时,PC指向CPU运行的下一条指令。每次取值后PC的值会自动修改以指向下一条指令,从而保证了指令按一定的顺序执行。当程序的执行顺序发生改变(如转移)时,需要修改PC的值。
V:溢出标志,V=1表示有溢出,V=0表示无溢出
程序正常执行时,每执行一条ARM指令,当前指令计数器增加4个字节
二 汇编语言
1.汇编指令格式
例子:ADDEQS R0,R1,#8;其中操作码为ADD,条件域cond为EQ,S表示该指令的执行影响CPSR寄存器的值,目的寄存器Rd为R0,第一个操作数寄存器Rd为R1,第二个操作数OP2为立即数#8
LDR R3,[R0,#2]! 指令执行后,R0 = R0 + 2
条件码 |
助记符后缀 |
标志 |
含义 |
0000 |
EQ |
Z置位 |
相等 |
0001 |
NE |
Z清零 |
不相等 |
0010 |
CS |
C指令 |
无符号数大于或等于 |
0011 |
CC |
C清零 |
无符号数小于 |
0100 |
MI |
N置位 |
负数 |
0101 |
PL |
N清零 |
正数或零 |
0110 |
VS |
V置位 |
溢出 |
0111 |
VC |
V清零 |
未溢出 |
1000 |
HI |
C置位Z清零 |
无符号数大于 |
1001 |
LS |
C清零Z置位 |
无符号数小于或等于 |
1010 |
GE |
N等于V |
带符号数大于或等于 |
1011 |
LT |
N不等于V |
带符号数小于 |
1100 |
GT |
Z清零且(N等于V) |
带符号数大于 |
1101 |
LE |
Z置位或(N不等于V) |
带符号数小于或等于 |
1110 |
AL |
忽略 |
无条件执行 |
例子:ADDEQ R4,R3,#1 相等则相加,即CPSR中Z置位时该指令执行,否则不执行。
助记符 |
指令功能描述 |
助记符 |
指令功能描述 |
ADC |
带进位加法指令 |
MRC |
从协处理器寄存器到ARM寄存器的数据传输指令 |
ADD |
加法指令 |
MRS |
传送CPSR或SPSR的内容到通用寄存器指令 |
AND |
逻辑与指令 |
MSR |
传送通用寄存器到CPSR或SPSR的指令 |
B |
分支指令 |
MUL |
32位乘法指令 |
BIC |
位清零指令 |
MLA |
32位乘加指令 |
BL |
带返回的分支指令 |
MVN |
数据取反传送指令 |
BLX |
带返回和状态切换的分支指令 |
ORR |
逻辑或指令 |
BX |
带状态切换的分支指令 |
RSB |
逆向减法指令 |
CDP |
协处理器数据操作指令 |
RSC |
带错位的逆向减法指令 |
CMN |
比较反值指令 |
SBC |
带错位减法指令 |
CMP |
比较指令 |
STC |
协处理器寄存器写入存储器指令 |
EOR |
异或指令 |
STM |
批量内存字写入指令 |
LDC |
存储器到协处理器的数据传输指令 |
STR |
寄存器到存储器的数据存储指令 |
LDM |
加载多个寄存器指令 |
SUB |
减法指令 |
LDR |
存储器到寄存器的数据加载指令 |
SWI |
软件中断指令 |
MCR |
从ARM寄存器到协处理器寄存器的数据传输指令 |
TEQ |
相等测试指令 |
MOV |
数据传送指令 |
TST |
位测试指令 |
寻址方式就是根据指令中操作数的信息来寻找操作数实际物理地址的方式
MOV R0,#15 #15就是立即数
ADD R0, R1, R2 将R1和R2的内容相加,其结果存放在寄存器R0中
LDR R0, [R4] 以寄存器R4的值作为操作数的地址,在存储器中取得一个操作数存入寄存器R0中
MOV R0,R1,LSL R3 将R1的值左移R3位,然后将结果存放到R0中
LDR R0,[R1,R2] R0 = [R1+R2]
后缀IA表示在每次执行玩加载/存储操作后,R0按自长度增加。
...
LDMFD R13!,{R0 - R4};
6.数据处理指令
1). MOV指令
MOV {MOV R0,#5 将立即数5传给R0
MVN R1,R2 将R2取反,结果保存到R1
RRX 带扩展的循环右移
ADD R0,R1,R2,LSL #2 R0 = R1 + (R2左移2位)
ADC R1,R3,R5 高32位相加,加上进位
SUB R0,R2,R3,LSL #1 R0 = R2 - (R3左移1位)
SBC R1,R3,R5 高32位相减,去除C的反码
RSC{
EOR{
ADDGT R0,R0,#5 如果R1>10,则执行ADDGT指令,将R0加5
CMN R0,R1 将R0和R1相加,并设置CPSR的值
MLAS R0,R1,R2,R3
7.数据加载与存储指令
助记符 |
说明 |
操作 |
LDR{}Rd,addr |
加载字数据 |
Rd = [addr] |
LDRB{}Rd,addr |
加载无符号字节数据 |
Rd = [addr] |
LDRT{}Rd,addr |
以用户模式加载字数据 |
Rd = [addr] |
LDRBT{}Rd,addr |
以用户模式加载无符号字节数据 |
Rd = [addr] |
LDRH{}Rd,addr |
加载无符号半字数据 |
Rd = [addr] |
LDRSB{}Rd,addr |
加载有符号字节数据 |
Rd = [addr] |
LDRSH{}Rd,addr |
加载有符号半字数据 |
Rd = [addr] |
STR{}Rd,addr |
存储字数据 |
[addr] = Rd |
STRB{}Rd,addr |
存储字节数据 |
[addr] = Rd |
STRT{}Rd,addr |
以用户模式存储字数据 |
[addr] = Rd |
STRBT{}Rd,addr |
以用户模式存储字节数据 |
[addr] = Rd |
STRH{}Rd,addr |
存储半字数据 |
[addr] = Rd |
LDM{}{type}Rn{!},regs |
多寄存器加载 |
reglist = [Rn...] |
STM{}{type}Rn{!},regs |
多寄存器存储 |
[Rn...] = reglist |
SWP{}Rd,Rm,[Rn] |
寄存器和存储器字数据交换 |
Rd=[Rn],[Rn]=Rm(Rn!=Rd或Rm) |
SWP{}B Rd,Rm,[Rn] |
寄存器和存储器字节数据交换 |
Rd = [Rn],[Rn] = Rm(Rn!=Rd或Rm) |
LDR R0,[R1],R2,LSL #2 将存储器地址为R1的字数据读入寄存器R0,并将新地址R1+R2*4写入R1
LDRB/STRB{
STRB指令用于从源寄存器中将一个8位的字节数据存储到存储器中,和LDRB相反。后缀T可选。
3). LDRH/STRH半字数据加载/存储指令
LDRH/STRH{
STRH指令用于从源寄存器中将一个16位的半字数据存储到存储器中,和LDRH相反。后缀T可选。
LDM/STM{
STM用于将寄存器列表所指向的多个寄存器中的值存入由基址寄存器所指向的一片连续存储器中,内存单元的起始地址为基址寄存器Rn的值,各个寄存器又寄存器列表regs表示。该指令一般用于多个寄存器数据的进栈操作。
EA:空递增堆栈
SWPB指令用于将寄存器Rn指向的存储器中的字节数据加载到目的寄存器Rd中,目的寄存器的高24位清零,同时将Rm中的字数据存储到Rn指向的存储器中。
BLX{cond}label Rm 带返回和状态切换的分支指令 | PC=label,T=1 PC; PC = Rm &0xffffffe,T=Rm[0] & 1;LR = BLX后面的第一条指令地址
B backword 无条件跳转到backword处执行
MOV R15,R14 复制返回地址到PC,实现子程序的返回
当通过BL或BLX指令调用子程序时,硬件自动将子程序返回地址保存在R14寄存器中。在子程序返回时,把LR的值复制到程序计数器PC即可实现子程序返回。
9.堆栈
LDMFD和STMFD分别指POP出栈和PUSH入栈