目录
简单的ARM程序
.text @表示当前为代码段
.global _start @将_start定义为全局符号
_start: @汇编入口
MOV R1,#1 @汇编指令
MOV R2,#2
MOV R3,#3
stop: @死循环防止程序跑飞
B stop
.end @汇编的结束
ARM指令集的分类
1.数据处理指令:主要用于数学运算,逻辑运算。
2.跳转指令:实现程序的跳转,本质是修改PC寄存器的内容。
3.Load/Srore指令:实现访问内存的读写。
4.状态寄存器传送指令:用于访问CPSR寄存器
5.软中断指令:触发软中断
6.协处理器指令:操作协处理器的指令。
ARM数据处理指令
ARM的数据处理指令主要用于对数据进行算术和逻辑运算,包括加、减、乘、除、位运算等。以下是一些常用的数据处理指令及其举例:
-
ADD指令:用于实现加法运算。例如:
ADD R0, R1, R2 ; 将R1和R2的值相加,结果存放到R0中 ADD R0, R1, #10 ; 将R1的值加上10,结果存放到R0中 ADD R0, R1, R2, LSL #3 ; 将R1的值加上R2乘8的值,结果存放到R0中
-
SUB指令:用于实现减法运算。例如:
SUB R0, R1, R2 ; 将R1的值减去R2的值,结果存放到R0中 SUB R0, R1, #10 ; 将R1的值减去10,结果存放到R0中 SUB R0, R1, R2, ASR #2 ; 将R1的值减去R2右移2位的值,结果存放到R0中
-
MUL指令:用于实现乘法运算。例如:
MUL R0, R1, R2 ; 将R1的值乘以R2的值,结果存放到R0中 MUL R0, R1, #10 ; 将R1的值乘以10,结果存放到R0中
-
DIV指令:用于实现除法运算。例如:
SDIV R0, R1, R2 ; 将R1的值除以R2的值,结果存放到R0中 UDIV R0, R1, #10 ; 将R1的值除以10,结果存放到R0中
-
AND/OR/XOR指令:用于实现位运算。例如:
AND R0, R1, R2 ; 将R1和R2的值进行逻辑与运算,结果存放到R0中 ORR R0, R1, #10 ; 将R1和10的值进行逻辑或运算,结果存放到R0中 EOR R0, R1, R2 ; 将R1和R2的值进行逻辑异或运算,结果存放到R0中
-
LSL/LSR/ASR指令:用于实现移位运算。例如:
LSL R0, R1, #2 ; 将R1的值左移2位,结果存放到R0中 LSR R0, R1, R2 ; 将R1的值右移R2位,结果存放到R0中 ASR R0, R1, #3 ; 将R1的值算术右移3位,结果存放到R0中
ARM跳转指令
ARM跳转指令是用于在程序中进行跳转的指令。下面是常用的ARM跳转指令详解和举例:
1.B (Branch)指令
B指令用于无条件跳转到另一个指令地址。
语法:B label
举例:
B loop (跳转到loop标记处)
2.BL (Branch with Link)指令
BL指令用于跳转到另一个指令地址,并记录当前指令地址。
语法:BL label
举例:
BL function1 (跳转到function1函数,并记录当前地址)
3.BX (Branch and Exchange)指令
BX指令用于跳转到另一个指令地址,并根据跳转目标地址的最低位决定执行模式。
语法:BX Rn (Rn为一个寄存器,存储跳转地址)
举例:
BX R0 (跳转到R0寄存器存储的地址)
4.BGT (Branch if Greater Than)指令
BGT指令用于比较两个寄存器的值,如果第一个寄存器的值大于第二个寄存器的值,则跳转到指定地址。
语法:BGT R0, R1, label
举例:
BGT R0, R1, loop1 (如果R0大于R1,则跳转到loop1标记处)
5.BEQ (Branch if Equal)指令
BEQ指令用于比较两个寄存器的值,如果两个寄存器的值相等,则跳转到指定地址。
语法:BEQ R0, R1, label
举例:
BEQ R0, R1, loop2 (如果R0和R1相等,则跳转到loop2标记处)
ARM的Load/Srore指令
ARM的Load/Store指令是用于从内存中加载数据以及将数据存储到内存中的指令。这些指令用于访问内存中的单个数据项,例如8位、16位、32位或64位数据,以及向内存中存储单个数据项。
Load指令的格式如下:
LDR{size}{cond} Rd, [Rn {, #offset}]
其中,size
表示数据的位数,可以是8、16、32或64位。cond
表示条件码,用于指定条件执行该指令。Rd
表示目的寄存器,存储从内存中读取的数据。Rn
表示基地址寄存器,指定要访问的内存地址。offset
表示可选的偏移量,用于指定要访问的内存地址的偏移量。
例如,以下指令将从内存地址R1+4
处读取32位数据,并将其存储到寄存器R0
中:
LDR R0, [R1, #4]
Store指令的格式如下:
STR{size}{cond} Rd, [Rn {, #offset}]
其中,size
和cond
的含义与Load指令相同。Rd
表示要存储到内存中的数据。Rn
和offset
的含义也与Load指令相同。
例如,以下指令将寄存器R0
中的32位数据存储到地址为R1+8
的内存中:
STR R0, [R1, #8]
需要注意的是,Load/Store指令只能访问对齐的内存地址。访问未对齐的内存地址将导致错误,并可能导致硬件异常。此外,对于ARMv7和更高版本的处理器,Load/Store指令还支持Atomic操作,可以实现原子读写操作。
ARM的状态寄存器传送指令
ARM的状态寄存器传送指令是一种将状态寄存器的值从一个寄存器传送到另一个寄存器的指令,它可以用来保存和恢复状态寄存器的值,以便在程序执行过程中控制程序的行为。
常用的状态寄存器包括程序状态寄存器(CPSR)和当前程序状态寄存器(CSPR)。其中,CPSR用于保存当前程序的执行状态(如标志位、模式、进位标志等),CSPR则用于保存当前程序在执行时的状态(如中断使能、暂停状态等)。
状态寄存器传送指令有两种形式,分别是MRS和MSR。其中,MRS指令用于将CPSR或CSPR的值传送到一个通用寄存器中,MSR指令则将通用寄存器中的值传送到CPSR或CSPR中。
例如,将CPSR的值传送到R0寄存器中,可以使用以下代码:
MRS R0, CPSR
将寄存器R0中的值传送到CSPR中,可以使用以下代码:
MSR CPSR_cxsf, R0
ARM软中断指令
ARM的软中断指令是一种在执行程序时,通过指令触发软中断,在指定的软中断号(0-255)下执行一段子程序的指令。软中断指令可以用于在程序执行期间调用一些系统功能和服务,比如操作系统的系统调用、异常处理等。
ARM的软中断指令由SWI指令实现,语法如下:
SWI value
其中,value代表了软中断号。在执行SWI指令时,处理器会进入中断服务程序中执行指定的子程序。软中断号0-255可以用于执行不同的系统功能,通常由操作系统内核定义和管理。
在ARM汇编语言中,可以使用SWI指令来触发软中断,例如:
SWI 0 //触发软中断0
在高级语言中(如C语言)可以通过嵌入汇编指令的方式调用SWI指令,例如:
__asm {
SWI 0 //触发软中断0
}
在执行软中断调用时,软件需要实现对应的中断服务程序来处理软中断,并根据中断号执行相应的子程序。因此,软中断指令是一种非常灵活、可扩展的指令,可以用于实现各种系统服务和功能。
ARM伪指令
.global symbol
将symbol声明成全局符号
.local symbol
将symbol声明成局部符号
ARM混合编程
方式一:汇编语言调用(跳转)C语言
MOV R1, #1
MOV R2, #2
BL func_c
MOV R3, #3
方式二:C语言调用(跳转)汇编语言
void func_c()
{
int a;
a++;
FUNC_ASM();
a--;
}
方式三:C内联(内嵌)汇编
void func_c()
{
int a;
a++;
asm
(
"MOV R6, #6\n"
"MOV R7, #7\n"
);
FUNC_ASM();
a--;
}