内容提要 ·ARM指令集 -ARM指令集分类与指令格式 ARM指令集 -ARM指令的寻址方式 -ARM指令集详解 -Thumb:指令及应用 李曦 ·ARM汇编程序设计基础 llxx@ustc.edu.cn 一系统初始化 调试环境 lboousic.edu.cn 5.1ARM微处理器的指令集概述 ARM指令集 5.1,IARM微处理器的指令的分类与格式 ·跳转指令: ·Load-store结构 -B 转指令。 带延回的蛛转折令。 BLX 带问和状态切换的洗转折令。 带状态切换的转指令。 ·指令分类 ·数据处理指令 ◆数据处理指令一使用和改变寄存器的值 位测试指令 ◆数据传送指令-把存储器的值拷贝到寄存器中(1oad)或 2 TEQ 相等测试折令 饰进位 把寄存器中的值拷贝到存储器中(stor©) 法指令 ◆拉制流指今 EOR 辑异支折令 BIC 位清除折令 上分支 。乘法指令与乘加指令 一分支和链接。保存返回的地址,以恢复最先的次序 MLA >陪入系统代玛 ◆程序状态寄存器(PSR)处理指令 程序状态寄存器存取指令 。RS程序状态寄存器到通用寄存的数据传送指令。 ◆协处理器指令 一MSR通用酱存器到程序状态寄存器的数据传送指令。 ◆异常产生指令 .edu.cn 37m .edu.cn /77 ARM指令集(续) 5.1.2指令的条件域 ·寄存器加载存储指令: LDB字节数据加我指令 ·所有的ARM指合都可以条件执行 R字数据加我指令 一DR半字数据加载指令 STR字数据存储指令 ST阳 字数据存储指令 妻整的执行5香取决于CPSR寄存器的N乙,CaaV际 ST连续数据存储指令 -所有的Thumb指合都可以解压成全部条件指 ·数据交换指令: -SP字数据交换指令 SPB字节数据交换指令 每一条ARM指令包含4位的条件码,位于指令的最高4位 ·移位元指令: [31:28] ,条件码共有16种 每种条件码可用两个字符表 S1辑左移 ASL算术左移 示,这两个字符可以添加在指今助记符的后面和指今同时 一LSR辑右移 ASR算术右移 使用, 0R循环右移 即贴带扩充的循环右移 -例如,跳转指合B可以加上后缀EQ变为BEQ表示“相等 ·协处理器指令 则跣转”,即当CPSR中的Z标志置位时发生跳转。 -P协处理器数据操作指令 -山C协处理署数据如我指令 -STC协处理器数据存指令 -RA处理器寄存器到协处理器寄存器的数据传送指令 -RC协处理器寄存器到A处理器寄存器的数据传送指令 ·在16种条件标志码中,只有15种可以使用 577
ARM指令集 李曦 llxx@ustc.edu.cn llxx@ustc.edu.cn 2/77 内容提要 • ARM指令集 – ARM指令集分类与指令格式 – ARM指令的寻址方式 – ARM指令集详解 – Thumb指令及应用 • ARM汇编程序设计基础 – 系统初始化 – 调试环境 llxx@ustc.edu.cn 3/77 5.1 ARM微处理器的指令集概述 5.1.1 ARM微处理器的指令的分类与格式 • Load-store结构 • 指令分类 数据处理指令 – 使用和改变寄存器的值 数据传送指令 – 把存储器的值拷贝到寄存器中 (load)或 把寄存器中的值拷贝到存储器中(store) 控制流指令 分支 分支和链接, 保存返回的地址,以恢复最先的次序 陷入系统代码 程序状态寄存器(PSR)处理指令 协处理器指令 异常产生指令 llxx@ustc.edu.cn 4/77 ARM指令集 • 跳转指令: – B 跳转指令。 BL 带返回的跳转指令。 – BLX 带返回和状态切换的跳转指令。 BX 带状态切换的跳转指令。 • 数据处理指令 – MOV 数据传送指令 MVN 数据取反传送指令 – CMP 比较指令 CMN 反值比较指令 – TST 位测试指令 TEQ 相等测试指令 – ADD 加法指令28 ADC 带进位加法指令 – SUB 减法指令 SBC 带借位减法指令 – RSB 逆向减法指令 RSC 带借位的逆向减法指令 – AND 逻辑与指令 ORR 逻辑或指令 – EOR 逻辑异或指令 BIC 位清除指令 • 乘法指令与乘加指令 – MUL 32 位乘法指令 MLA 32 位乘加指令 – SMULL 64 位有符号数乘法指令 SMLAL 64 位有符号数乘加指令 – UMULL 64 位无符号数乘法指令 UMLAL 64 位无符号数乘加指令 • 程序状态寄存器存取指令 – MRS 程序状态寄存器到通用寄存器的数据传送指令。 – MSR 通用寄存器到程序状态寄存器的数据传送指令。 llxx@ustc.edu.cn 5/77 ARM指令集(续) • 寄存器加载/存储指令 : – LDR 字数据加载指令 LDRB 字节数据加载指令 – LDRH 半字数据加载指令 STR 字数据存储指令 – STRB 字节数据存储指令 STRH 半字数据存储指令 – LDM 连续数据加载指令 STM 连续数据存储指令 • 数据交换指令 : – SWP 字数据交换指令 SWPB 字节数据交换指令 • 移位元指令: – LSL 逻辑左移 ASL 算术左移 – LSR 逻辑右移 ASR 算术右移 – ROR 循环右移 RRX 带扩充的循环右移 • 协处理器指令 – CDP 协处理器数据操作指令 – LDC 协处理器数据加载指令 – STC 协处理器数据存储指令 – MCR ARM处理器寄存器到协处理器寄存器的数据传送指令 – MRC 协处理器寄存器到ARM处理器寄存器的数据传送指令 llxx@ustc.edu.cn 6/77 • 所有的ARM指令都可以条件执行 – 指令的执行与否取决于CPSR寄存器的N, Z, C and V标 志位 – 所有的Thumb指令都可以解压成全部条件指令 • 每一条ARM指令包含4位的条件码,位于指令的最高4位 [31:28]。条件码共有16种,每种条件码可用两个字符表 示,这两个字符可以添加在指令助记符的后面和指令同时 使用。 – 例如,跳转指令B可以加上后缀EQ变为BEQ表示“相等 则跳转”,即当CPSR中的Z标志置位时发生跳转。 • 在16种条件标志码中,只有15种可以使用。 31 28 0 Cond 5.1.2 指令的条件域
指令的条件两15种) 条件执行 条件 助记符后银 标志 含义 0000 EO Z置位 相等 ·条件执行可避免使用分支指令 0001 NE Z清零 不相等 ·Example C置位 无符号数大于或等于 0011 CC C清零 无符号数小于 CMP rO,#5 0100 N置位 负数 BEQ BYPASS :ifc0:5){ ADDr1,r1.ro r1:=r1+r0-r2 0101 N清零 正数或零 SUBr1,r1,r2 注意:条件不成立时, 0110 争 V置位 滋出 BYPASS: 该指令被忽略,等于执 0111 V清零 未漫出 行了一条NOP. 1000 C爱位清零 无符号数大于 使用条件执行 if ((a==b)&&(c==d))e+ 1001 LS C清零Z置位 无符号数小于或等于 CMP rO,#5 1010 GE N等于V 带符号数大于或等于 ADDNE r1,r1,ro: CMP rO,r1 1011 LT N不等于V 带符号数小干 SUBNE r1,r1,r2: CMPEQ r2,r3 1100 GT Z清零且(N等于V) 带符号数大于 ADDEQr4,r4,#1 101 E Z置位或(N不等于V) 带符号数小于或等于 obe:add 2-letter condition after the 3-etter opcode 1110 AL 复略 无第件执行 boxustc.cdu.cn lbooustc.edu.cn 指令格式 ARM7TDMI指令集编码 ◆3地址指令格式 >在ARM状态中使用 1001 fbits n bits n bits n bits 00001001 function op 1 addr.op 2 addr.dest.addr. ◆2地址指令格式 >在ARM和THUMB状态下使用 fbits n bits n bits function op 1 addr.dest.addr. xustc.edu.cn 77 .edu.cn 077 ARM存储器访问指令 单寄存器存储 ARM存储器访问指令一单寄存器存储 LDR和STR一字和无符号字节加载/存储指令编码 LDR和STR一丰字和有特号字节如载/存储指令编玛 B为1表示字节诗问 为0美示幸诗司 W表示回写 5为1表示有特号诗问, 为0表示无特号诗问 P表示前/后变址 L用于制加载L为1 P表示前/后支址 日为1表示来字诗问,为 指个执行的景件码 或存陆(L为0 指执守的件码 0表示字节诗问 318272石7为为73疗1动9165 1711 31282726252232224209 1615 1211 875430 cdb1Puwm U表示如/减 为指的寻址方 1为0,偏量为 为指命的寻址方式 12位 1为0时,偏移量为 Rd为源/g标寺存互 偏移量为寺存移 Rd为源/日标奇存三 12位立即教,为1对, Rn为基址寺存器 Rn为基址寺存耳 偏移量为寺存器移 L用于区刮加我L为1) U表示加/减 W表示四写 或存储L为0) 1177 27
llxx@ustc.edu.cn 7/77 条件执行 • 条件执行可避免使用分支指令 • Example CMP r0, #5 ; BEQ BYPASS ; if (r0!=5) { ADD r1, r1, r0 ; r1:=r1+r0-r2 SUB r1, r1, r2 ; } BYPASS: ... CMP r0, #5 ; ADDNE r1, r1, r0; SUBNE r1, r1, r2; ... 使用条件执行 Note: add 2 –letter condition after the 3-letter opcode ; if ((a==b) && (c==d)) e++; CMP r0, r1 CMPEQ r2, r3 ADDEQ r4, r4, #1 注意:条件不成立时, 该指令被忽略,等于执 行了一条NOP。 llxx@ustc.edu.cn 8/77 条件码 助记符后缀 标 志 含 义 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 忽略 无条件执行 指令的条件码(15种) llxx@ustc.edu.cn 9/77 3地址指令格式 在ARM状态中使用 2地址指令格式 在ARM和 THUMB 状态下使用 指令格式 llxx@ustc.edu.cn 10/77 ARM7TDMI指令集编码 llxx@ustc.edu.cn 11/77 ARM存储器访问指令——单寄存器存储 •LDR和STR——字和无符号字节加载/存储指令编码 指令执行的条件码 I为0时 , 偏 移 量 为 12位立即数,为1时, 偏 移 量 为 寄 存 器 移 位 P表示前/后变址 U表示加/减 B为1表示字节访问, 为0表示字访问 W表示回写 为指令的寻址方式 Rd为源/目标寄存器 Rn为基址寄存器 L用于区别加载(L为1) 或存储(L为0) llxx@ustc.edu.cn 12/77 ARM存储器访问指令——单寄存器存储 •LDR和STR——半字和有符号字节加载/存储指令编码 指令执行的条件码 I为0时 , 偏 移 量 为 12位立即数,为1时, 偏 移 量 为 寄 存 器 移 位 P表示前/后变址 U表示加/减 W表示回写 为指令的寻址方式 Rd为源/目标寄存器 Rn为基址寄存器 L用于区别加载(L为1) 或存储(L为0) S为1表示有符号访问, 为0表示无符号访问 H为1表示半字访问,为 0表示字节访问
5.2ARM指令的寻址方式 5.2.1立即寻址 ·立即寻址 ·立即寻址也叫立即数寻址 ·寄存器寻址 ·操作数本身就在指令中给出,只要取出指令也就取 ·寄存器间接寻址 到了操作数。这个操作数被称为立即数。 ·例如: ·基址变址寻址 ·多寄存器寻址 ADD RO,RO,#1 :R0-R0+1 ·相对寻址 ADD RO,RO,#0x3f RO+-R0+0x3f ·堆栈寻址 一第二个源操作数即为立即数,要求以“#”为前缀 ·对于以十六进制表示的立即数,还要求在"料”后加上0x”或最 .edu.cn 13m loousic.edu.cn 14m 有效立即数问题 5.2.2寄存器寻址 c附o9a工 ·寄存器中的数值作为操作数 并不是所有立即数都是有效的 在32位指令编码中存放32位立即数的方法是: 一这种寻址方式是各类微处理器经常采用的一种 方式,也是一种执行效率较高的寻址方式。 一在ARM漱据处理指令中,第二操作数域12位 老接品 针高餐用秀 -以下指令: 桃平棉家 ADD RO,R1,R2 RO+R1+R2 示成 <immediate>-immed8循环右移(2 x rotate imm) 如:movR4,#0x8000000A ADD R3,R2,R1,LSL #3 ;#0x8000000A由0xA8循环右移0x2位得到 :R3=R2+R1<<3 15m .edu.cn 16/77 ARM指令一第2个操作数 ARM指令——第2个操作数 Rn Rm ARM指令的基本格式如下: Rm..shift-—寺存器移住方式 预处理 预处 [桶形移位器 copcode>(<cond>)(s)Rd>,<Rn>,Koperand2>) 符奇存器的移位结果作为操作 理 教,但Rm值保持不变(移位 灵活的使用第2个絲作教“operand2”能妙提高代码效车。 接作不萌耗新外的对间)。 结果N 它有如下的形式: ALU "immed8r一常数表达式,立即寻址; 移位方法如下: Rd Rm一奇存器寻址方式: 提作积 说明 操作胡 说明 Rm.shift-一寺存器移位方式: ASR粉算术右移n位 ROR 畅环右移n位 LSLn逆辑左移n位 RRX 带打展的循环右移1位 wO"工 ] LSR #n 边辑右移n位 Type Rs 公盟 X ust.cdu.m 177 877
llxx@ustc.edu.cn 13/77 5.2 ARM指令的寻址方式 • 立即寻址 • 寄存器寻址 • 寄存器间接寻址 • 基址变址寻址 • 多寄存器寻址 • 相对寻址 • 堆栈寻址 llxx@ustc.edu.cn 14/77 • 立即寻址也叫立即数寻址 • 操作数本身就在指令中给出,只要取出指令也就取 到了操作数。这个操作数被称为立即数。 • 例如: ADD R0,R0,#1 ;R0←R0+1 ADD R0,R0,#0x3f ;R0←R0+0x3f –第二个源操作数即为立即数,要求以“#”为前缀 • 对于以十六进制表示的立即数,还要求在“#”后加上“0x”或“&” 5.2.1 立即寻址 llxx@ustc.edu.cn 15/77 有效立即数问题 • 并不是所有立即数都是有效的 • 在32位指令编码中存放32位立即数的方法是: – 在ARM数据处理指令中,第二操作数域12位 – 每个立即数采用一个8位的常数(bit[7:0])循环右移偶数 位而间接得到,其中循环右移的位数由一个4位二进制 (bit[11:8])的两倍表示 • 如果立即数记作<immediate>,8位常数记作immed_8,4位的循 环右移值记作rotate_imm,有效的立即数是由一个8位的立即数 循环右移偶数位得到,可以表示成: • <immediate>=immed_8 循环右移(2×rotate_imm) 如:mov R4, #0x8000 000A ;#0x8000 000A由0xA8循环右移0x2位得到 llxx@ustc.edu.cn 16/77 5.2.2 寄存器寻址 • 寄存器中的数值作为操作数 – 这种寻址方式是各类微处理器经常采用的一种 方式,也是一种执行效率较高的寻址方式。 – 以下指令: ADD R0,R1,R2 ;R0←R1+R2 ADD R3,R2,R1,LSL #3 ;R3=R2+R1<<3 llxx@ustc.edu.cn 17/77 ARM指令的基本格式如下: ARM指令——第2个操作数 <opcode> {<cond>} {S} <Rd> ,<Rn>{,<operand2>} 灵活的使用第2个操作数“operand2”能够提高代码效率。 它有如下的形式: #immed_8r——常数表达式,立即寻址; Rm——寄存器寻址方式; Rm,shift——寄存器移位方式; llxx@ustc.edu.cn 18/77 ARM指令——第2个操作数 Rm,shift——寄存器移位方式 将寄存器的移位结果作为操作 数,但Rm值保持不变(移位 操作不消耗额外的时间)。 移位方法如下: 操作码 说明 操作码 说明 ASR #n 算术右移n位 ROR #n 循环右移n位 LSL #n 逻辑左移n位 RRX 带扩展的循环右移1位 LSR #n 逻辑右移n位 Type Rs Type为移位的一种类型,Rs为 偏移量寄存器,低8位有效。 ALU 桶形移位器 Rd 结果N 预 处 理 未 预 处 理 Rn Rm
桶形移位器操作 桶形移位器操作(续) 助记符说明 LSL移位热作: 移位操作结果 Y值 8 LSL逻辑左移 xLSLy x<<y #0-310rRs LSR移振作: LSR逻辑右移 xLSRy (unsigned)x>>y #1-320rRs -Ⅲ ASR算术右移 x ASR y (signed)x>>Y #1-320rRs ASR移往播作: ROR 算术左移 x RORy ((unsigned)x>>yl(x<<32- #1-320rRs 0) ROR移往振作: RRX 扩展的循环 x RRX y (c flag<<31) none 右移 ((unsigned)x>>1) RRX移往恭作: xusic.edu.cn 19m lboousic.edu.cn 207m 5.23寄存器间接寻址 5.2.4基址变址寻址 ② 寄存器间接寻址:以寄存器中的值作为操 ·将基址寄存器的内容与指令中给出的地址偏移量 作数的地址,而操作数本身存放在存储器 相加,从而得到一个操作数的有效地址。 一“变址”,改变基址 中。 一变址寻址方式常用于访问某基地址附近的地址 LDR RO,[R1] :R0←-[R1] 单元。 STR RO,[RI] [R1]+R0 ·变址方式: 前变址、自动变址(“回写”!)、后变址(“回写”!)、 偏移变址 ADD RO,R1,[R2] :R0←R1+[R2] LDRR0,[R1,#4]:R0-[R1十4],前 :可用?,查 LDRR0,[R1,#4]!:R0-[R1+4]、R1-R1十4,自 LDRR0,[R1],#4:R0-[R1]、R1-R1十4,后 LDRR0,【R1,R2】:R0-[R1+R2],偏 xBustc.edu.cn 21m .edu.cn 22m Pre or Post Indexed Addressing? 52.5多寄存器寻址 ·Pre-indexed::STRx0,【r1,121 12 020 采用多寄存器寻址方式,一条指令可以完成多个寄存器值 的传送。这种寻址方式可以用一条指令完成传送最多16个 驰 通用寄存器的值。 Auio-update formsTRx0,【r1,12】 以下指令: LDMIA RO,(R1,R2,R3,R4) ·Post-indexed:sTRr0,【r1],12 :R1-[RO] :R2-[RO+4] Offset :R3-[R0+8] 12 020c 0 :R4-[R0+12] 该指令的后缀1A表示在每次执行完加载/存储操作后,R0 按字长度增加,因此,指令可将连续存储单元的值传送到 R1R4。 2477
llxx@ustc.edu.cn 19/77 桶形移位器操作 助记符 说明 移位操作 结果 Y值 LSL 逻辑左移 x LSL y x<<y #0-31 or Rs LSR 逻辑右移 x LSR y (unsigned)x>>y #1-32 or Rs ASR 算术右移 x ASR y (signed)x>>Y #1-32 or Rs ROR 算术左移 x ROR y ((unsigned)x>>y|(x<<32- y)) #1-32 or Rs RRX 扩展的循环 右移 x RRX y (c flag<<31)| ((unsigned)x>>1) none llxx@ustc.edu.cn 20/77 桶形移位器操作(续) LSL移位操作: 0 LSR移位操作: 0 ASR移位操作: ROR移位操作: RRX移位操作: C llxx@ustc.edu.cn 21/77 5.2.3 寄存器间接寻址 寄存器间接寻址:以寄存器中的值作为操 作数的地址,而操作数本身存放在存储器 中。 LDR R0,[R1] ;R0←[R1] STR R0,[R1] ;[R1]←R0 ADD R0,R1,[R2] ;R0←R1+[R2] ;可用??? ,查 llxx@ustc.edu.cn 22/77 5.2.4 基址变址寻址 • 将基址寄存器的内容与指令中给出的地址偏移量 相加,从而得到一个操作数的有效地址。 – “变址”,改变基址 – 变址寻址方式常用于访问某基地址附近的地址 单元。 • 变址方式: 前变址、自动变址(“回写”!)、后变址(“回写”!)、 偏移变址 LDR R0,[R1,#4] ;R0←[R1+4],前 LDR R0,[R1,#4]! ;R0←[R1+4]、R1←R1+4,自 LDR R0,[R1],#4 ;R0←[R1]、R1←R1+4,后 LDR R0,[R1,R2] ;R0←[R1+R2],偏 0x5 0x5 r1 0x200 Base Register 0x200 r0 0x5 Source Register for STR Offset 12 0x20c r1 0x200 Original Base Register 0x200 r0 0x5 Source Register for STR Offset 12 0x20c r1 0x20c Updated Base Register Auto-update form: STR r0,[r1,#12]! Pre or Post Indexed Addressing? • Pre-indexed: STR r0,[r1,#12] • Post-indexed: STR r0,[r1],#12 llxx@ustc.edu.cn 24/77 5.2.5 多寄存器寻址 采用多寄存器寻址方式,一条指令可以完成多个寄存器值 的传送。这种寻址方式可以用一条指令完成传送最多16个 通用寄存器的值。 以下指令: LDMIA R0,{R1,R2,R3,R4} ;R1←[R0] ;R2←[R0+4] ;R3←[R0+8] ;R4←[R0+12] 该指令的后缀IA表示在每次执行完加载/存储操作后,R0 按字长度增加,因此,指令可将连续存储单元的值传送到 R1~R4
5.2.6相对寻址 52.7堆栈寻址 堆栈是一种数据结构,按先进后出(First In Last Out 与基址变址寻址方式相类似,相对寻址以程序计数器PC的 FL0)的 当前值为基地址,指令中的地址标号作为偏移量,将两者 相加之后得到操作数的有效地址。 按SP指向的位置,分: 以下程序段完成子程序的调用和返回,跳转指令L采用了 满堆栈(Full Stack):当堆栈指针指向最后压入堆栈的数据 时: 相对寻址方式: 空堆栈(Empty Stack):当堆栈指针指向下一个将要放入数据 的空位置时: BL NEXT :跳转到子程序NEXT处执行 根据堆栈的生成方式,分: NEXT: 递增堆栈(Ascending Stack):当堆栈由低地址向高地址生 成时: MOV PC.LR :从子程序返回 递减堆栈(Decending Stack):当堆栈由高地址向低地址生成 时: xusic.edu.cn 25m 26m ARM微处理器支持的堆栈工作方式② 栈操作图示 满递增堆栈FA g s 一堆栈指针指向最后压入的数据,且由低地址向高地址生成。 满递减堆栈FD 0x418 r5 SP 一堆栈指针指向最后压入的数据,且由高地址向低地址生成。 空递增堆栈EA 一堆栈指针指向下一个将要放入致据的空位置,且由低地址向高地址 生成 Dd SR r5 0x400 ·空递减堆栈ED r5 一罐技指针指向下一个将要政入数据的空仓置。且由高地址向低地址 ·堆找操作指令 0 LDM 0x3e8 STM Uco1上移植:do1reO3G0T1堆栈由高地址向低地址增长 xustc.edu.cn 277元 .edu.cn 277 子程序调用 ② 程序嵌套调用 BL SUBR branch to SUBR 物w网中 子程序里再调用子程序时会政变14,因 return to here 此遇到多层程序调用时得保存14 SUBR BL SUBI branch to SUB! sub entry point MoV pe,r14 i return 8nmx131,【0-2,141 save rogs BL SUB2 入Pc即可(没有奏似RET的语句) = 世 如果子程序要使用14的话,需要保存 存在里面的返回地址。 EDMEA E131,[r0-2,pe)return SUB2 MOV pC,:14 return lboophustc.edu.cn 077
llxx@ustc.edu.cn 25/77 5.2.6 相对寻址 与基址变址寻址方式相类似,相对寻址以程序计数器PC的 当前值为基地址,指令中的地址标号作为偏移量,将两者 相加之后得到操作数的有效地址。 以下程序段完成子程序的调用和返回,跳转指令BL采用了 相对寻址方式: BL NEXT ;跳转到子程序NEXT处执行 …… NEXT: …… MOV PC,LR ;从子程序返回 5.2.7 堆栈寻址 堆栈是一种数据结构,按先进后出(First In Last Out, FILO)的方式工作,使用一个称作“堆栈指针”的专用寄存 器(SP)指示当前的操作位置,堆栈指针总是指向栈顶。 按SP指向的位置,分: 满堆栈(Full Stack):当堆栈指针指向最后压入堆栈的数据 时; 空堆栈(Empty Stack):当堆栈指针指向下一个将要放入数据 的空位置时; 根据堆栈的生成方式,分: 递增堆栈(Ascending Stack):当堆栈由低地址向高地址生 成时; 递减堆栈(Decending Stack):当堆栈由高地址向低地址生成 时; llxx@ustc.edu.cn 26/77 llxx@ustc.edu.cn 27/77 • 满递增堆栈FA – 堆栈指针指向最后压入的数据,且由低地址向高地址生成。 • 满递减堆栈FD – 堆栈指针指向最后压入的数据,且由高地址向低地址生成。 • 空递增堆栈EA – 堆栈指针指向下一个将要放入数据的空位置,且由低地址向高地址 生成。 • 空递减堆栈ED –堆栈指针指向下一个将要放入数据的空位置,且由高地址向低地址 生成。 • 堆栈操作指令 – LDM – STM Ucosii移植:#define OS_STK_GROWTH 1 /* 堆栈由高地址向低地址增长 ARM微处理器支持的堆栈工作方式 llxx@ustc.edu.cn 28/77 栈操作图示 llxx@ustc.edu.cn 29/77 子程序调用 BL SUBR ; branch to SUBR … ; return to here … SUBR … ; sub entry point … MOV pc, r14 ; return • 转跳时返回地址存放在r14中,子程序 返回时只要把原先保存在r14的地址装 入pc即可(没有类似RET的语句) • 如果子程序要使用r14的话,需要保存 存在里面的返回地址。 llxx@ustc.edu.cn 30/77 程序嵌套调用 子程序里再调用子程序时会改变r14,因 此遇到多层程序调用时得保存r14 BL SUB1 ; branch to SUB! … … SUB1 STMFA r13!, {r0-r2, r14} ; save regs BL SUB2 … … LDMFA r13!, {r0-r2, pc} ; return SUB2 … MOV pc, r14 ; return