[size=x-large]ARM七种工作模式:[/size]
用户模式 usr
快速中断 fiq
外部中断 irq
管理模式 svc
数据访问终止 abt
系统模式 sys
未定义指令异常 und
[size=x-large]ARM指令集[/size]
[size=medium]一.跳转指令[/size]
1 直接修改PC指针的值, 实现在[color=red]4GB[/color]的地址空间中任意跳转, 在跳转以前结合MOV LR,PC使用
2 专门的跳转指令-->从当前指令向前或向后32MB的地址空间的跳转
B-->跳转指令
BL-->带返回的跳转指令
BLX-->带返回和状态切换的跳转指令
BX-->带状态切换的跳转指令
B指令的格式:
[color=red]B{条件} 目标位置[/color]
例如:
B Label 程序无条件跳转到标号Label处执行
CMP R1, #0
BEQ Label-->当CPSR寄存器中的Z条件码置位时, 程序跳转到标号为Label处执行
BL指令的格式
[color=red]BL{条件} 目标地址[/color]
跳转之前, 会在R14中保存PC地址, 实现子程序调用
例如:
BL Label 无条件跳转到标号Label处执行, 并将当前的PC值保存到R14中
BLX指令的格式:
[color=red]BLX 目标地址[/color]
跳转到目标地址, 将PC保存到R14中, 并将处理器的工作状态从ARM切换到Thumb
BX指令的格式
[color=red]BX 目标地址[/color]
跳转,并切换至Thumb状态
[size=medium]二.数据处理指令[/size]
MOV指令
[color=red]MOV{条件}{S} 目的寄存器, 源操作数[/color]
参数不能使内存
S选项决定指令的操作是否影响CPSR中的条件标志位
示例:
MOV R1, R0; 将R0的值传送到R1
MOV PC, R14;将R14的值传送到PC, 当用于子程序返回
MOV R1, R0, LSL #3; 将寄存器R0的值左移3位后传到R1中
MVN指令
[color=red]MVN{条件}{S} 目的寄存器, 源操作数[/color]
与MOV区别: 将源操作数取反后, 存入目标寄存器
例如:
MVN R0, #0xff; R0<=0xffffff00
CMP指令
[color=red]CMP{条件} 操作数1, 操作数2[/color]
比较两个操作数, 影响CPSR中的条件标志位
指令条件:
EQ-->Z置位-->相等
NE-->Z清零-->不相等
CS-->C置位-->无符号数大于或等于
CC-->C清零-->无符号数小于
MI-->N置位-->负数
PL-->N清零-->正数或零
VS-->V置位-->溢出
VC-->V清零-->未溢出
HI-->C置位Z清零-->无符号数大于
LS-->C清零Z置位-->无符号数小于或等于
GE-->N等于V-->带符号数大于或等于
LT-->N不等于V-->带符号数小于
GT-->Z清零且(N等于V)-->等符号书大于
LE-->Z置位或(N不等于V)-->带符号数小于或等于
AL-->忽略-->无条件执行
TST指令
[color=red]TST{条件} 操作数1, 操作数2[/color]
两操作数进行按位与运算
操作数1是要测试的数据, 操作数2是位掩码, 当位与结果为0时, EQ被设置
例如:
TST R1, #%1; 用于测试R1的最低位是否置位(%表示二进制数)
ADD指令
[color=red]ADD{条件}{S} 目的寄存器, 操作数1, 操作数2[/color]
将两操作数之和放入目的寄存器
操作数1应是一个寄存器
操作数2可是一个寄存器, 被移位的寄存器或是一个立即数
示例
ADD R0, R1, R2; R0=R1+R2
ADD R0, R1, #256; R0=R1+256
ADD R0, R2, R3, LSL#1; R0=R2+(R3<<1)
SUB指令
[color=red]SUB{条件}{S} 目的寄存器, 操作数1, 操作数2[/color]
SUB指令将操作数1减去操作数2, 并将结果放入目标寄存器
操作数1应是一个寄存器
操作数2可是一个寄存器, 被移位的寄存器或是一个立即数
示例
SUB R0, R1, R2; R0=R1-R2
SUB R0, R1, #256; R0=R1-256
SUB R0, R2, R3, LSL#1; R0=R2-(R3<<1)
AND指令
[color=red]AND{条件}{S} 目的寄存器, 操作数1, 操作数2[/color]
将操作数1和操作数2的逻辑与结果放入目的寄存器
操作数1应是一个寄存器
操作数2可是一个寄存器, 被移位的寄存器或是一个立即数
常用于设置操作数1的某些位
示例:
AND R0, R0, #3; 保持R0的0和1位, 其余位清零
ORR指令
[color=red]ORR{条件}{S} 目的寄存器, 操作数1, 操作数2[/color]
将操作数1和操作数2的逻辑或结果放入目的寄存器
操作数1应是一个寄存器
操作数2可是一个寄存器, 被移位的寄存器或是一个立即数
常用于设置操作数1的某些位
示例:
ORR R0, R0, #3; 将R0的0和1位置位, 其余位不变
BIC指令
[color=red]BIC{cond}{S} Rd, Rn, operand2[/color]
BIC用于清除Rn中的某些位, 并把结果放入Rd中, 操作数operand2为32位掩码, 掩码某位置1, 则清除该位
例如
BIC R0, R0, #%1011; 将R0的0,1,3置零, 其余位不变
MUL指令
[color=red]MUL{条件}{S} 目的寄存器, 操作数1, 操作数2[/color]
MUL将两操作数的乘积放入目的寄存器
例如:
MUL R0, R1, R2;R0=R1xR2
MULS R0, R1, R2;同上, 并设置CPSR相关条件标志位
[size=x-large]三. 程序状态指令[/size]
MRS指令
[color=red]MRS{条件} 通用寄存器, 程序状态寄存器[/color]
将CPSR或SPSR的内容传到通用寄存器中
例如:
MRS R0, CPSR;传送CPSR的内容到R0
MRS R0, SPSR;传送SPSR的内容到R0
MRS指令
[color=red]MSR{条件} 程序状态寄存器_<域>, 操作数[/color]
将操作数的内容传到状态寄存器的特定域
32为的程序状态寄存器可分为4个域
[31-24]条件标志位域, 用f表示
[23-16]状态位, 用s表示
[15-8]为扩展位域, 用x表示
[7-0]为控制位域,用c表示
例如:
MSR CPSR, R0; 用R0为CPSR赋值
MSR CPSR_c, RO; R0位CPSR的控制位域赋值
[size=x-large]四. 加载/存储指令[/size]
用于在[color=red]寄存器和储存器[/color]之间传送数据
加载-->将存储器中的指令读入寄存器
存储-->将寄存器的数据写入存储器
LDR指令
[color=red]LDR{条件} 目的寄存器, <存储器地址>[/color]
从存储器中将一个32位的字数据传入目的寄存器
例如
LDR R0,[R1];将存储器地址为R1的字数据读入R0
LDR R0,[R1,R2];将存储器地址为R1+R2的字数据读入R0
LDR R0,[R1,#8];将存储器地址为R1+8的字数据读入R0
LDR R0.[R1,R2]!;将存储器地址为R1+R2的字数据写入R0, 再将R1+R2写入R1
STR指令
[color=red]STR{条件} 源寄存器, <存储器地址>[/color]
将源寄存器中的32位字数据传送到存储器中
示例:
STR R0, [R1], #8;将R0中的字数据写入R1为地址的存储器中,并将新地址R1+8写入R1
STR R0, [R1+8];将R0中的字数据写入以R1+8为地址的存储器中
批量加载/存储 LDM STM
[color=red]LDM{条件}{类型} 基址寄存器{! }, 寄存器列表{^ }[/color]
类型:
IA 每次传送后地址加1
IB 每次传送前地址加1
DA 每次传送后地址减1
DB 每次传送前地址减1
FD 满递减堆栈
ED 空递减堆栈
FA 满递增堆栈
EA 空递增堆栈
示例:
STMFD R13!, {R0, R4-R12, LR};!表示将堆栈指针写回R13
将寄存器列表中的寄存器存入堆栈
LDMFD R13!, {R0, R4-R12, PC}
将堆栈内容恢复到寄存器
SWP指令
SWP{条件} 目的寄存器, 源寄存器1, [源寄存器2]
将源寄存器2所指向的存储器中的字数据传送到目的寄存器,
同时将源寄存器1中的字数据传送到2指向的存储器
显然: 当源寄存器1和目的寄存器为同一寄存器时, 将交换寄存器和存储器的内容
示例:
SWP R0, R0, [R2]; R2指向的存储器与R0交换数据
[size=x-large]五. 移位操作[/size]
ARM指令集中, 移位不是单独的指令, 只能指令格式中的一个字段
[color=red]LSL 逻辑左移
ASL 算数左移
LSR 逻辑右移
ASR 算数右移
ROR 循环右移, 左端用右端移出的位来填充
ASL和LSL等价[/color]
LSL格式:
[color=red]通用寄存器, LSL操作数[/color]
左移,补零
例如:
MOV R0, R1, LSL#2;将R1的内热闹过左移两位传到R0
MOV R0, R1, ROR#2
[size=x-large]六. 异常产生指令[/size]
SWI 软件中断指令
BKPI 断点中断指令
用户模式 usr
快速中断 fiq
外部中断 irq
管理模式 svc
数据访问终止 abt
系统模式 sys
未定义指令异常 und
[size=x-large]ARM指令集[/size]
[size=medium]一.跳转指令[/size]
1 直接修改PC指针的值, 实现在[color=red]4GB[/color]的地址空间中任意跳转, 在跳转以前结合MOV LR,PC使用
2 专门的跳转指令-->从当前指令向前或向后32MB的地址空间的跳转
B-->跳转指令
BL-->带返回的跳转指令
BLX-->带返回和状态切换的跳转指令
BX-->带状态切换的跳转指令
B指令的格式:
[color=red]B{条件} 目标位置[/color]
例如:
B Label 程序无条件跳转到标号Label处执行
CMP R1, #0
BEQ Label-->当CPSR寄存器中的Z条件码置位时, 程序跳转到标号为Label处执行
BL指令的格式
[color=red]BL{条件} 目标地址[/color]
跳转之前, 会在R14中保存PC地址, 实现子程序调用
例如:
BL Label 无条件跳转到标号Label处执行, 并将当前的PC值保存到R14中
BLX指令的格式:
[color=red]BLX 目标地址[/color]
跳转到目标地址, 将PC保存到R14中, 并将处理器的工作状态从ARM切换到Thumb
BX指令的格式
[color=red]BX 目标地址[/color]
跳转,并切换至Thumb状态
[size=medium]二.数据处理指令[/size]
MOV指令
[color=red]MOV{条件}{S} 目的寄存器, 源操作数[/color]
参数不能使内存
S选项决定指令的操作是否影响CPSR中的条件标志位
示例:
MOV R1, R0; 将R0的值传送到R1
MOV PC, R14;将R14的值传送到PC, 当用于子程序返回
MOV R1, R0, LSL #3; 将寄存器R0的值左移3位后传到R1中
MVN指令
[color=red]MVN{条件}{S} 目的寄存器, 源操作数[/color]
与MOV区别: 将源操作数取反后, 存入目标寄存器
例如:
MVN R0, #0xff; R0<=0xffffff00
CMP指令
[color=red]CMP{条件} 操作数1, 操作数2[/color]
比较两个操作数, 影响CPSR中的条件标志位
指令条件:
EQ-->Z置位-->相等
NE-->Z清零-->不相等
CS-->C置位-->无符号数大于或等于
CC-->C清零-->无符号数小于
MI-->N置位-->负数
PL-->N清零-->正数或零
VS-->V置位-->溢出
VC-->V清零-->未溢出
HI-->C置位Z清零-->无符号数大于
LS-->C清零Z置位-->无符号数小于或等于
GE-->N等于V-->带符号数大于或等于
LT-->N不等于V-->带符号数小于
GT-->Z清零且(N等于V)-->等符号书大于
LE-->Z置位或(N不等于V)-->带符号数小于或等于
AL-->忽略-->无条件执行
TST指令
[color=red]TST{条件} 操作数1, 操作数2[/color]
两操作数进行按位与运算
操作数1是要测试的数据, 操作数2是位掩码, 当位与结果为0时, EQ被设置
例如:
TST R1, #%1; 用于测试R1的最低位是否置位(%表示二进制数)
ADD指令
[color=red]ADD{条件}{S} 目的寄存器, 操作数1, 操作数2[/color]
将两操作数之和放入目的寄存器
操作数1应是一个寄存器
操作数2可是一个寄存器, 被移位的寄存器或是一个立即数
示例
ADD R0, R1, R2; R0=R1+R2
ADD R0, R1, #256; R0=R1+256
ADD R0, R2, R3, LSL#1; R0=R2+(R3<<1)
SUB指令
[color=red]SUB{条件}{S} 目的寄存器, 操作数1, 操作数2[/color]
SUB指令将操作数1减去操作数2, 并将结果放入目标寄存器
操作数1应是一个寄存器
操作数2可是一个寄存器, 被移位的寄存器或是一个立即数
示例
SUB R0, R1, R2; R0=R1-R2
SUB R0, R1, #256; R0=R1-256
SUB R0, R2, R3, LSL#1; R0=R2-(R3<<1)
AND指令
[color=red]AND{条件}{S} 目的寄存器, 操作数1, 操作数2[/color]
将操作数1和操作数2的逻辑与结果放入目的寄存器
操作数1应是一个寄存器
操作数2可是一个寄存器, 被移位的寄存器或是一个立即数
常用于设置操作数1的某些位
示例:
AND R0, R0, #3; 保持R0的0和1位, 其余位清零
ORR指令
[color=red]ORR{条件}{S} 目的寄存器, 操作数1, 操作数2[/color]
将操作数1和操作数2的逻辑或结果放入目的寄存器
操作数1应是一个寄存器
操作数2可是一个寄存器, 被移位的寄存器或是一个立即数
常用于设置操作数1的某些位
示例:
ORR R0, R0, #3; 将R0的0和1位置位, 其余位不变
BIC指令
[color=red]BIC{cond}{S} Rd, Rn, operand2[/color]
BIC用于清除Rn中的某些位, 并把结果放入Rd中, 操作数operand2为32位掩码, 掩码某位置1, 则清除该位
例如
BIC R0, R0, #%1011; 将R0的0,1,3置零, 其余位不变
MUL指令
[color=red]MUL{条件}{S} 目的寄存器, 操作数1, 操作数2[/color]
MUL将两操作数的乘积放入目的寄存器
例如:
MUL R0, R1, R2;R0=R1xR2
MULS R0, R1, R2;同上, 并设置CPSR相关条件标志位
[size=x-large]三. 程序状态指令[/size]
MRS指令
[color=red]MRS{条件} 通用寄存器, 程序状态寄存器[/color]
将CPSR或SPSR的内容传到通用寄存器中
例如:
MRS R0, CPSR;传送CPSR的内容到R0
MRS R0, SPSR;传送SPSR的内容到R0
MRS指令
[color=red]MSR{条件} 程序状态寄存器_<域>, 操作数[/color]
将操作数的内容传到状态寄存器的特定域
32为的程序状态寄存器可分为4个域
[31-24]条件标志位域, 用f表示
[23-16]状态位, 用s表示
[15-8]为扩展位域, 用x表示
[7-0]为控制位域,用c表示
例如:
MSR CPSR, R0; 用R0为CPSR赋值
MSR CPSR_c, RO; R0位CPSR的控制位域赋值
[size=x-large]四. 加载/存储指令[/size]
用于在[color=red]寄存器和储存器[/color]之间传送数据
加载-->将存储器中的指令读入寄存器
存储-->将寄存器的数据写入存储器
LDR指令
[color=red]LDR{条件} 目的寄存器, <存储器地址>[/color]
从存储器中将一个32位的字数据传入目的寄存器
例如
LDR R0,[R1];将存储器地址为R1的字数据读入R0
LDR R0,[R1,R2];将存储器地址为R1+R2的字数据读入R0
LDR R0,[R1,#8];将存储器地址为R1+8的字数据读入R0
LDR R0.[R1,R2]!;将存储器地址为R1+R2的字数据写入R0, 再将R1+R2写入R1
STR指令
[color=red]STR{条件} 源寄存器, <存储器地址>[/color]
将源寄存器中的32位字数据传送到存储器中
示例:
STR R0, [R1], #8;将R0中的字数据写入R1为地址的存储器中,并将新地址R1+8写入R1
STR R0, [R1+8];将R0中的字数据写入以R1+8为地址的存储器中
批量加载/存储 LDM STM
[color=red]LDM{条件}{类型} 基址寄存器{! }, 寄存器列表{^ }[/color]
类型:
IA 每次传送后地址加1
IB 每次传送前地址加1
DA 每次传送后地址减1
DB 每次传送前地址减1
FD 满递减堆栈
ED 空递减堆栈
FA 满递增堆栈
EA 空递增堆栈
示例:
STMFD R13!, {R0, R4-R12, LR};!表示将堆栈指针写回R13
将寄存器列表中的寄存器存入堆栈
LDMFD R13!, {R0, R4-R12, PC}
将堆栈内容恢复到寄存器
SWP指令
SWP{条件} 目的寄存器, 源寄存器1, [源寄存器2]
将源寄存器2所指向的存储器中的字数据传送到目的寄存器,
同时将源寄存器1中的字数据传送到2指向的存储器
显然: 当源寄存器1和目的寄存器为同一寄存器时, 将交换寄存器和存储器的内容
示例:
SWP R0, R0, [R2]; R2指向的存储器与R0交换数据
[size=x-large]五. 移位操作[/size]
ARM指令集中, 移位不是单独的指令, 只能指令格式中的一个字段
[color=red]LSL 逻辑左移
ASL 算数左移
LSR 逻辑右移
ASR 算数右移
ROR 循环右移, 左端用右端移出的位来填充
ASL和LSL等价[/color]
LSL格式:
[color=red]通用寄存器, LSL操作数[/color]
左移,补零
例如:
MOV R0, R1, LSL#2;将R1的内热闹过左移两位传到R0
MOV R0, R1, ROR#2
[size=x-large]六. 异常产生指令[/size]
SWI 软件中断指令
BKPI 断点中断指令