STM 常用汇编指令
BX Rm 带状态切换跳转指令 PC<----Rm ,切换状态(Rm[0]=1,thumb,Rm[0]=0,ARM)
%F2 表示跳转到当前指令后面的标号 2 处
%B0 表示跳转到当前指令前面的标号 0 处
[ ----- IF
;
----- ENDIF
| ----- ELSE ;
]
IF logical expression
存器,或一个立即数。该指令使用进位标志来表示借位,这样就可以做大于 32 位的减法。
注意不要忘记设置 S 后缀来更改进位标志。该指令可用于有符号数或无符号数的减法运算。
指令示例:
SUBS R0,R1,R2
; R0 = R1 - R2 - !C,并根据结果设置 CPSR 的进位标志
位
(10)BX 带状态切换的跳转指令
含义:(1)SP-->R8 SP=SP+4
(2)SP=SP+4 (3)SP-->R9 (4)SP=SP+4 (5)SP-->PC (6)
ldmia sp!
{ r0-r7 pc }^
^ 表示将 spsr 的值赋给 cpsr
B lable
跳转指令 PC<---lable
BL lable 带链接跳转指令
LR<----PC-4, PC<---lable
连续存储单元的值传送到 R1~R4。
(9)SBC 指令的格式为:
SBC{条件}{S} 目的寄存器,操作数 1,操作数 2
SBC 指令用于把操作数 1 减去操作数 2,再减去 CPSR 中的 C 条件标志位的反码,并将结果
存放到目的寄存器中。操作数 1 应是一个寄存器,操作数 2 可以是一个寄存器,被移位的寄
LDR R0,[R1,R2] ! ;将存储器地址为 R1+R2 的字数据读入寄存器 R0,并将新地址 R1
+R2 写入 R1
LDR R0,[R1,#8] ! ;将存储器地址为 R1+8 的字数据读入寄存器 R0,并将新地址 R1
+8 写入 R1。
LDR R0,[R1],R2
;将存储器地址为 R1 的字数据读入寄存器 R0,并将新地址 R1
(8)采用多寄存器寻址方式,一条指令可以完成多个寄存器值的传送。这种寻址方式可以
用一条指令完成传送最多 16 个通用寄存器的值。以下指令:
LDMIA
R0,{R1,R2,R3,R4}
;R1←[R0]
;R2←[R0
+4]
;R3←[R0+8]
;R4←[R0+
12]
该指令的后缀 IA 表示在每次执行完加载/存储操作后,R0 按字长度增加,因此,指令可将
MSR{<cond>} CPSR_f | SPSR_f,#<32-bit immediate> MSR{<cond>} CPSR_<field> | SPSR_<field>,Rm msr cpsr, r0 mrs r0, cpsr
6、异常中断指令 异常中断指令可以分为一下两种: 软件中断指令(SWI) 断点指令(BKPT—仅用于 v5T 体系) 软件中断指令 SWI 用于产生 SWI 异常中断,用来实现在用户模式下对操作系统中特权模式的 程序的调用;断点中断指令 BKPT 主要用于产生软件断点,供调试程序用。 7、其他伪指令 .extern main .text .global _start _start:
件中引用,而且无论当前源文件是否引用该标号,该标号均会被加入到当前源文件的符号表
中。
IMPORT
BootloaderMain
IMPORT
MMUSetup
(4)BL 带返回的跳转指令
(5)BEQ 表示“相等则跳转”,即当 CPSR 中的 Z 标志置位时发生跳转
B
Label
;程序无条件跳转到标号 Label 处执行
作操作数 2,则此后的有 GT 后缀的指令将可以执行。 指令示例: CMP R1,R0 ;将寄存器 R1 的值与寄存器 R0 的值相减,并根据结果设置 CPSR 的标志位 CMP R1,#100 ;将寄存器 R1 的值与立即数 100 相减,并根据结果设置 CPSR 的标志位
(13)批量数据加载/存储指令 LDM(或 STM)指令的格式为: LDM(或 STM){条件}{类型} 基址寄存器{!},寄存器列表{∧} LDM(或 STM)指令用于从由基址寄存器所指示的一片连续存储器到寄存器列表所指示的多 个寄存器之间传送数据,该指令的常见用途是将多个寄存器的内容入栈(SDM)或出栈(LDM)。 其中,{类型}为以下几种情况: IA 每次传送后地址加 1; IB 每次传送前地址加 1; DA 每次传送后地址减 1; DB 每次传送前地址减 1; FD 满递减堆栈; ED 空递减堆栈; FA 满递增堆栈; EA 空递增堆栈; {!}为可选后缀,若选用该后缀,则当数据传送完毕之后,将最后的地址写入基址寄存器, 否则基址寄存器的内容不改变。
器将要执行的操作,源寄存器为 ARM 处理器的寄存器,目的寄存器 1 和目的寄存器 2 均为
协处理器的寄存器。
指令示例:
MCR
P3,3,R0,C4,C5,6
;该指令将 ARM 处理器寄存器 R0 中的数据传送到
协处理器 P3 的寄存器 C4 和 C5 中。
(12)CMP 指令的格式为: CMP{条件} 操作数 1,操作数 2 CMP 指令用于把一个寄存器的内容和另一个寄存器的内容或立即数进行比较,同时更新 CPSR 中条件标志位的值。该指令进行一次减法运算,但不存储结果,只更改条件标志位。 标志位表示的是操作数 1 与操作数 2 的关系(大、小、相等),例如,当操作数 1 大于操
;
CPSR--->r1
MSR (写状态寄存器) MSR cpsr_c, #0xD3 ; CPSR[7...0] = 0xD3
STMFD SP! {R8-R9}
含义:(1)SP=SP-4 字节 (2) R9--->SP (3)SP=SP-4 (4) R8-->SP
LDMFD SP! {R8-R9,PC}
CMP R1,#0
;当 CPSR 寄存器中的 Z 条件码置位时,程序跳转到标号 Label 处执行
BEQ Label
(6)LDR 指令的格式为:
LDR{条件} 目的寄存器,<存储器地址>
LDR 指令用于从存储器中将一个 32 位的字数据传送到目的寄存器中。该指令通常用于从存
储器中读取 32 位的字数据到通用寄存器,然后对数据进行处理。当程序计数器 PC 作为目
{TRUE}
(2)GET(或 INCLUDE) GET 伪指令用于将一个源文件包含到当前的源文件中,并将被包含的源文件在当前位置进行 汇编处理。可以使用 INCLUDE 代替 GET。 INCLUDE ..\\..\\kernel\\oal\\startup.s
(3)IMPORT 伪指令用于通知编译器要使用的标号在其他的源文件中定义,但要在当前源文
在嵌入式开发中,汇编程序常常用于非常关键的地方,比如系统启动时初始化,进出中断时 的环境保护,恢复等对性能有要求的地方。
ARM 指令集可以分为六大类,分别为数据处理指令、Load/Store 指令、跳转指令、程序状态
寄存器处理指令、协处理器指令和异常产生指令。
ARM 指令使用的基本格式如下:
〈opcode〉{〈cond〉}{S}
〈Rd〉,〈Rn〉{,〈operand2〉}
opcode 操作码;指令助记符,如 LDR、STR 等。
cond 可选的条件码;执行条件,如 EQ、NE 等。
S 可选后缀;若指定“S”,则根据指令执行结果更新 CPSR 中的条件码。
Rd 目标寄存器。
Rn 存放第 1 操作数的寄存器。
operand2 第 2 个操作数
b funa .... funa:
b funb ....
funb: .... 2、数据传送指令 mov,地址读取伪指令 ldr mov 指令可以把一个寄存器的值赋给另外一个寄存器,或者把一个常数赋给寄存器。 mov r1, r2
mov r1,#1024 mov 传送的常数必须能用立即数来表示。当不能用立即数表示时,可以用 ldr 命令来赋值。 ldr 是伪命令,不是真实存在的指令,编译器会把它扩展成真正的指令;如果该常数能用“立 即数”来表示,则使用 mov 指令,否则编译时将该常数保存在某个位置,使用内存读取指令 把它读出来。 ldr r1, = 1024
3、内存访问指令 ldr、str、ldm、stm ldr 既可以指低至读取伪指令,也可以是内存访问指令。当他的第二个参数前面有'='时标 伪指令,否则表内存访问指令。 ldr 指令从内存中读取数据到寄存器,str 指令把寄存器的指存储到内存中,他们的操作数 都是 32 位的。
ldr r1, [r2, #4] ldr r1,[r2] ldr r1,[r2], #4 str r1 ,[r2, #4] str r1, [r2] str r1, [r2],#4 寄存器传送指令可以用一条指令将 16 个可见寄存器(R0~R15)的任意子集合(或全部)存 储到存储器或从存储器中读取数据到该寄存器集合中。与单寄存器存取指令相比,多寄存器 数据存取可用的寻址模式更加有限。多寄存器存取指令的汇编格式如下: LDM/STM{<cond>}<add mode> Rn{!}, <registers>
[logical expression
Instructions Instructions
{ELSE |
Instructions Instructions
} ]
ENDIF
(1)GBLL 伪指令用于定义一个全局的逻辑变量,并初始化为{False}。