常用▲RM指令集及汇编 ver:10.12 相加,结果写回到Rn中.Rn不允许是R15.指令举例如下 LDR Rd, [Rn], #0x04 地址对准-大多数情况下,必须保证用于32位传送的地址是32位对准的 加载/存储字和无符号字节指令举例如下 加载R5指定地址上的数据(字),放入R2中 STRR1,[RO,#0x04];将R1的数据存储到R0+0x04存储单元,RO值不变 LDRB R3, [R2,#1 读取R2地址上的一字节数据,并保存到R3中,R2=R3+1 STRB R6, [R7 读R6的数据保存到R7指定的地址中,只存储一字节数据 加载/存储半字和带符号字节.这类LDR/STR指令可能加载带符字节\加载带符号半 字、加载/存储无符号半字.偏移量格式、寻址方式与加载/存储字和无符号字节指令相 同.指令格式如下 LDR{cond}SBRd<地址〉;加载指定地址上的数据(带符号字节),放入Rd中 IDR{cond}SHRd,<地址〉;加载指定地址上的数据(带符号字节),放入Rd中 LDR{cond}HRd,<地址〉;加载半字数据,放入Rd中,即Rd最低16位有效,高16位清零 sTR{cond}HRd,<地址〉;存储半字数据,要存储的数据在Rd,最低16位有效 说明:带符号位半字/字节加载是指带符号位加载扩展到32位;无符号位半字加载 是指零扩展到32位 地址对准—对半字传送的地址必须为偶数.非半字对准的半字加载将使Rd内容不 可靠,非半字对准的半字存储将使指定地址的2字节存储内容不可靠. 加载/存储半字和带符号字节指令举例如下 LDRSB R[RO,R3];将R0+R3地址上的字节数据读出到R1,高24位用符号位扩展 LDRSH R1,[R9];将R9地址上的半字数据读出到R1,高16位用符号位扩展 LDRH R6,[R2],#2;将R2地址上的半字数据读出到R6,高16位用零扩展,,R2=R2+1 SHRH R1,[RO,#2]!;将R1的数据保存到R2+2地址中,只存储低2字节数据,RO=R0+2 LDR/STR指令用于对内存变量的访问,内存缓冲区数据的访问、查表、外围部件的 控制操作等等,若使用LDR指令加载数据到PC寄存器,则实现程序跳转功能,这样也 就实现了程序散转 变量的访问 NumCoun 0x40003000;定义变量 Num Count %%嗡%%%嗡%嗡%嗡嗡吼嗡%嗡嗡嗡哈嗡嗡%%嗡哈 By宛城布衣QQ:57523799emai:mcu8031@163cm 第13页
常用 ARM 指令集及汇编 Ver:1.0.12 相加,结果写回到 Rn 中.Rn 不允许是 R15.指令举例如下: LDR Rd,[Rn],#0x04 地址对准--大多数情况下,必须保证用于 32 位传送的地址是 32 位对准的. 加载/存储字和无符号字节指令举例如下: LDR R2,[R5] ;加载 R5 指定地址上的数据(字),放入 R2 中 STR R1,[R0,#0x04] ;将 R1 的数据存储到 R0+0x04 存储单元,R0 值不变 LDRB R3,[R2],#1 ;读取 R2 地址上的一字节数据,并保存到 R3 中,R2=R3+1 STRB R6,[R7] ;读R6的数据保存到R7指定的地址中,只存储一字节数据 加载/存储半字和带符号字节.这类 LDR/STR 指令可能加载带符字节\加载带符号半 字、加载/存储无符号半字.偏移量格式、寻址方式与加载/存储字和无符号字节指令相 同.指令格式如下: LDR{cond}SB Rd,<地址> ;加载指定地址上的数据(带符号字节),放入 Rd 中 LDR{cond}SH Rd,<地址> ;加载指定地址上的数据(带符号字节),放入 Rd 中 LDR{cond}H Rd,<地址> ;加载半字数据,放入 Rd 中,即 Rd 最低 16 位有效,高 16 位清零 STR{cond}H Rd,<地址> ;存储半字数据,要存储的数据在 Rd,最低 16 位有效 说明:带符号位半字/字节加载是指带符号位加载扩展到 32 位;无符号位半字加载 是指零扩展到 32 位. 地址对准--对半字传送的地址必须为偶数.非半字对准的半字加载将使 Rd 内容不 可靠,非半字对准的半字存储将使指定地址的 2 字节存储内容不可靠. 加载/存储半字和带符号字节指令举例如下: LDRSB R1[R0,R3] ;将 R0+R3 地址上的字节数据读出到 R1,高 24 位用符号位扩展 LDRSH R1,[R9] ;将 R9 地址上的半字数据读出到 R1,高 16 位用符号位扩展 LDRH R6,[R2],#2 ;将 R2 地址上的半字数据读出到 R6,高 16 位用零扩展,,R2=R2+1 SHRH R1,[R0,#2]!;将 R1 的数据保存到 R2+2 地址中,只存储低 2 字节数据,R0=R0+2 LDR/STR 指令用于对内存变量的访问,内存缓冲区数据的访问、查表、外围部件的 控制操作等等,若使用 LDR 指令加载数据到 PC 寄存器,则实现程序跳转功能,这样也 就实现了程序散转。 变量的访问 NumCount EQU 0x40003000 ;定义变量 NumCount IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII By 宛城布衣 QQ:57523799 email: mcu8031@163.com 第 13 页
常用▲RM指令集及汇编 ver:10.12 RO,= Num Count;使用LDR伪指令装载 NumCount的地址到RO LDR RI, ROI 取出变量值 R1,R1,#1 NumCount=Num Count+1 保存变量值 GPIo设置 GPIO-BASE EQU OXe0028000 定义GPI0寄存器的基地址 LDR RO =GPIO-BASE LDRR1,=0x0OFF00;装载32位立即数,即设置值 STRR1,[RO,#0x0CJ;I0DIR=0x00FFF0, IODIR的地址为0xE00280C MOVR1,#0x00F00000 STRR1,[RO,#0x04];I0ET=0x00F0000,10SET的地址为0xE0028004 程序散转 MOVR2,R2,LSL#2;功能号乘上4,以便查表 LDR PC,[PC,R2];查表取得对应功能子程序地址,并跳转 NOP FUN-TAB DCD FUN-SUBO DCD FUN-SUBI DCD FUN-SUB2 ◆LDM和STM 批量加载/存储指令可以实现在一组寄存器和一块连续的内存单元之间传输数 据.LDM为加载多个寄存器,STM为存储多个寄存器.允许一条指令传送16个寄存器的任 何子集或所有寄存器.指令格式如下: %%嗡%%%嗡%嗡%嗡嗡吼嗡%嗡嗡嗡哈嗡嗡%%嗡哈 By宛城布衣QQ:57523799emai:mcu8031@163cm
常用 ARM 指令集及汇编 Ver:1.0.12 … LDR R0,=NumCount ;使用 LDR 伪指令装载 NumCount 的地址到 R0 LDR R1,[R0] ;取出变量值 ADD R1,R1,#1 ;NumCount=NumCount+1 STR R1,[R0] ;保存变量值 … GPIO 设置 GPIO-BASE EQU 0Xe0028000 ;定义 GPIO 寄存器的基地址 … LDR R0,=GPIO-BASE LDR R1,=0x00FFFF00 ;装载 32 位立即数,即设置值 STR R1,[R0,#0x0C] ;IODIR=0x00FFFF00, IODIR 的地址为 0xE002800C MOV R1,#0x00F00000 STR R1,[R0,#0x04] ;IOSET=0x00F00000,IOSET 的地址为 0xE0028004 … 程序散转 … MOV R2,R2,LSL #2 ;功能号乘上 4,以便查表 LDR PC,[PC,R2] ;查表取得对应功能子程序地址,并跳转 NOP FUN-TAB DCD FUN-SUB0 DCD FUN-SUB1 DCD FUN-SUB2 … LDM 和 STM 批量加载/存储指令可以实现在一组寄存器和一块连续的内存单元之间传输数 据.LDM 为加载多个寄存器,STM 为存储多个寄存器.允许一条指令传送 16 个寄存器的任 何子集或所有寄存器.指令格式如下: IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII By 宛城布衣 QQ:57523799 email: mcu8031@163.com 第 14 页
常用▲RM指令集及汇编 ver:10.12 LDM{cond}<模式〉Rn{!}, reglist{"} STM{cond}<模式〉Rn{!}, reglist{"} LDM/STM的主要用途是现场保护、数据复制、参数传送等。其模式有8种,如下:(前 面4种用于数据块的传输,后面4种是堆栈操作) (1)IA:每次传送后地址加4 (2)IB:每次传送前地址加4 3)DA:每次传送后地址减4 (4)DB:每次传送前地址减4 (5)FD:满递减堆栈 (6)ED:空递增堆栈 (7)FA:满递增堆栈 (8)EA:空递增堆栈 其中,寄存器Rn为基址寄存器,装有传送数据的初始地址,Rn不允许为R15;后缀“!” 表示最后的地址写回到R中;寄存器列表 reglist可包含多于一个寄存器或寄存器范围, 使用“,”分开,如{R1,R2,R6-R9},寄存器排列由小到大排列;“”后缀不允许在用户 模式呈系统模式下使用,若在LDM指令用寄存器列表中包含有PC时使用,那么除了正 常的多寄存器传送外,将SPSR拷贝到CPSR中,这可用于异常处理返回;使用“^”后 缀进行数据传送且寄存器列表不包含PC时,加载存储的是用户模式的寄存器,而不是 当前模式的寄存器 地址对准一一这些指令忽略地址的位[1:0] 批量加载/存储指令举例如下 LDMIA R0!,{R3-R9};加载R0指向的地址上的多字数据,保存到R3~R9中,RO值更新 STMIA R1!,{R3-R9};将R3~R9的数据存储到R1指向的地址上,R1值更新 STMFD SP!,{R0-R7,LR};现场保存,将R0~R7、LR入栈 LDMFD SP!,{R0-R7,PC};恢复现场,异常处理返回 在进行数据复制时,先设置好源数据指针,然后使用块拷贝寻址指令 LDMIA/STMIA LDMIB/ STMIE、 LDMDA/ STMDA、LDDB/STMB进行读取和存储。而进行堆栈操作时,则要 先设置堆栈指针,一般使用SP然后使用堆栈寻址指令 STMFD/ LDMFD、 STMED。 LDMED、 STMFA/ LDMFA、 STMEA/LDMEA实现堆栈操作 %%嗡%嗡嗡%嗡%嗡嗡吼嗡%嗡嗡嗡吼哈嗡嗡%嗡 By宛城布衣QQ:57523799emai:mcu8031@163cm 第15页
常用 ARM 指令集及汇编 Ver:1.0.12 LDM{cond}<模式> Rn{!},reglist{^} STM{cond}<模式> Rn{!},reglist{^} LDM /STM 的主要用途是现场保护、数据复制、参数传送等。其模式有 8 种,如下:(前 面 4 种用于数据块的传输,后面 4 种是堆栈操作) (1) IA:每次传送后地址加 4 (2) IB:每次传送前地址加 4 (3) DA:每次传送后地址减 4 (4) DB:每次传送前地址减 4 (5) FD:满递减堆栈 (6) ED:空递增堆栈 (7) FA:满递增堆栈 (8) EA:空递增堆栈 其中,寄存器Rn为基址寄存器,装有传送数据的初始地址,Rn不允许为R15;后缀“!” 表示最后的地址写回到Rn中;寄存器列表reglist可包含多于一个寄存器或寄存器范围, 使用“,”分开,如{R1,R2,R6-R9},寄存器排列由小到大排列;“^”后缀不允许在用户 模式呈系统模式下使用,若在 LDM 指令用寄存器列表中包含有 PC 时使用,那么除了正 常的多寄存器传送外,将 SPSR 拷贝到 CPSR 中,这可用于异常处理返回;使用“^”后 缀进行数据传送且寄存器列表不包含 PC 时,加载/存储的是用户模式的寄存器,而不是 当前模式的寄存器。 地址对准――这些指令忽略地址的位[1:0] 批量加载/存储指令举例如下: LDMIA R0!,{R3-R9} ;加载 R0 指向的地址上的多字数据,保存到 R3~R9 中,R0 值更新 STMIA R1!,{R3-R9} ;将 R3~R9 的数据存储到 R1 指向的地址上,R1 值更新 STMFD SP!,{R0-R7,LR} ;现场保存,将 R0~R7、LR 入栈 LDMFD SP!,{R0-R7,PC}^;恢复现场,异常处理返回 在进行数据复制时,先设置好源数据指针,然后使用块拷贝寻址指令 LDMIA/STMIA、 LDMIB/STMIB、LDMDA/STMDA、LDMDB/STMDB 进行读取和存储。而进行堆栈操作时,则要 先设置堆栈指针,一般使用 SP 然后使用堆栈寻址指令 STMFD/LDMFD、STMED。LDMED、 STMFA/LDMFA、STMEA/LDMEA 实现堆栈操作。 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII By 宛城布衣 QQ:57523799 email: mcu8031@163.com 第 15 页
常用▲RM指令集及汇编 ver:10.12 多寄存器传送指令示意图如图所示,其中R1为指令执行前的基址寄存器,R1则为指 令执行完后的基址寄存器 R 4008H 4004H 400OH a)指令 STMIA R1!,{R5-R7 R54008H 4004H 4000H b)指令 STMIB R1!,{R5-R7 R54008H 4004H 400OH c)指令 STMDA RI!,{R5-R7} R64008H R54004H 4000H d)指令 STMDB R1!,{R5-R7} 数据是存储在基址寄存器的地址之上还是之下,地址是在存储第一个值之前还是之 后增加还是减少 %%嗡%嗡嗡%嗡%嗡嗡吼嗡%嗡嗡嗡吼哈嗡嗡%嗡 By宛城布衣QQ:57523799emai:mcu8031@163cm
常用 ARM 指令集及汇编 Ver:1.0.12 多寄存器传送指令示意图如图所示,其中R1为指令执行前的基址寄存器,R1则为指 令执行完后的基址寄存器. R7 R6 R5 4008H 4004H 4000H R1’ R1 a)指令 STMIA R1!,{R5-R7} R7 R6 R5 4008H 4004H 4000H R1’ R1 b)指令 STMIB R1!,{R5-R7} R7 R6 R5 4008H 4004H 4000H R1 R1’ c)指令 STMDA R1!, {R5-R7} R7 R6 4008H R5 4004H 4000H R1 R1’ d)指令 STMDB R1!,{R5-R7} 数据是存储在基址寄存器的地址之上还是之下,地址是在存储第一个值之前还是之 后增加还是减少. IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII By 宛城布衣 QQ:57523799 email: mcu8031@163.com 第 16 页
常用▲RM指令集及汇编 ver:10.12 多寄存器传送指令映射 向上生长 向下生长 两 STMIB LDMIB 之前 LIMED 增加 STMFA STMIA LDMIA 之后 STMEA LDMFD 之前 STMDB LDMEA STMFD 增加 STMDA 之后 LDMDA LDMFA STMED 使用LDM/STM进行数据复制 LDRR0,= SrcData;设置源数据地址 RI=DstData 设置目标地址 LDMIA RO, R2-R9H 加载8字数据到寄存器R2R9 STMIA RI,R2 R9I 存储寄存器R2R9到目标地址 使用LDM/SIM进行现场寄存器保护,常在子程序中或异常处理使用 SENDBYTE STMFD SP!,{RO-R7,LR};寄存器入堆 DELAY 调用 DELAY子程序 LDMFD SP!,{R0-R7,PC};恢复寄存器,并返回 ◆SwP 寄存器和存储器交换指令.SWP指令用于将一个内存单元(该单元地址放在寄存器 Rn中)的内容读取到一个寄存器Rd中,同时将另一个寄存器Rm的内容写入到该内存单 元中.使用SW可实现信号量操作 指令格式如下 SWP) B Rd, Rm, [Rn] %%%%%%嗡%哈嗡% By宛城布衣QQ:57523799emai:mcu8031@163cm 第17页
常用 ARM 指令集及汇编 Ver:1.0.12 多寄存器传送指令映射 向上生长 向下生长 满 空 满 空 STMIB LDMIB 之前 STMFA LDMED STMIA LDMIA 增加 之后 STMEA LDMFD LDMDB STMDB 之前 LDMEA STMFD LDMDA STMDA 增加 之后 LDMFA STMED 使用 LDM/STM 进行数据复制: … LDR R0,=SrcData ;设置源数据地址 LDR R1,=DstData ;设置目标地址 LDMIA R0,{R2-R9} ;加载 8 字数据到寄存器 R2~R9 STMIA R1,{R2~R9} ;存储寄存器 R2~R9 到目标地址 使用 LDM/STM 进行现场寄存器保护,常在子程序中或异常处理使用: SENDBYTE STMFD SP!,{R0-R7,LR} ;寄存器入堆 … BL DELAY ;调用 DELAY 子程序 … LDMFD SP!,{R0-R7,PC} ;恢复寄存器,并返回 SWP 寄存器和存储器交换指令.SWP 指令用于将一个内存单元(该单元地址放在寄存器 Rn 中)的内容读取到一个寄存器 Rd 中,同时将另一个寄存器 Rm 的内容写入到该内存单 元中.使用 SWP 可实现信号量操作. 指令格式如下: SWP{cond}{B} Rd,Rm,[Rn] IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII By 宛城布衣 QQ:57523799 email: mcu8031@163.com 第 17 页