




已阅读5页,还剩105页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
任课教师 栗华 课号 0123305810 100 sdlh 嵌入式系统原理及应用教程 第三章ARM寻址方式及指令系统 汇编语言编程是编译效率最高 最直接的编程方法 指令集是汇编语言程序设计的基础 本章旨在通过对ARM指令集的详细讲解及大量汇编示例的讲解使读者掌握ARM汇编指令的编写方法及编写技巧 本章内容 ARM指令集概述ARM的寻址方式ARM指令详细介绍 3 1ARM指令集概述 ARM指令集是32位的 程序的启动都是从ARM指令集开始 本节从以下三个方面介绍 指令分类及指令格式条件执行指令集编码 指令分类及指令格式 ARM指令使用的基本格式如下 opcode cond S Rd Rn operand2 是必须项 是可选项如 ADDSR4 R0 R2 R4 R0 R2 指令格式中符号说明 opcode操作码 指令助记符 如ADD STR等 cond可选的条件码 执行条件 如EQ NE等 S可选后缀 若指定 S 则根据指令执行结果更新CPSR中的条件码 Rd目标寄存器 Rn存放第1操作数的寄存器 op2第2个操作数 操作码 目的操作数 第一操作数 第二操作数 立即数操作 在数据处理指令中 第二操作数除了可以是寄存器 还可以是一个立即数 如果我们只是希望把一个常数加到寄存器 而不是两个寄存器相加 我们可以用立即数值取代第二操作数 如下面例子 立即数用前面加一个 的数值常量来表示 ADDR3 r3 1 r3 r3 1ANDR8 r7 ff r8 r7 7 0 TMD7寄存器移位操作 在ARM数据处理指令中 第二操作数还有一种特有的形式 寄存器移位操作 即允许第二个寄存器操作数在同第一操作数运算之前完成移位操作 例如 ADDr3 r2 r1 LSL 3 r3 r2 8 r1 设置条件码 ARM的任何数据处理指令都能通过增加 S 操作码来设置条件码 N Z C和V 数据处理指令加了 S 后 算术操作 在此包含CMP和CMN 根据算术运算的结果设置所有的标志位 CPSR和SPSR的格式 条件域表1 条件域表2 条件执行 所有的ARM指令集都可以是有条件执行的 ARM指令根据CPSR中的条件位自动判断是否执行指令 在条件满足时 指令执行 否则指令被忽略 在ARM的指令编码表中 统一占用编码的最高四位 31 28 来表示 条件码 即 cond 条件转移 ARM指令集编码 ARM指令集是以32位二进制编码的方式给出的 大部分的指令编码中定义了第一操作数 第二操作数 目的操作数 条件标志影响位以及每条指令所对应的不同功能实现的二进制位 每条32位ARM指令都具有不同的二进制编码方式 和不同的指令功能相对应 编码表如下 TMD153 2ARM寻址方式 ARM指令系统支持如下7种寻址方式 立即寻址寄存器寻址寄存器间接寻址基址加偏址寻址堆栈寻址块拷贝寻址相对寻址 3 2 1立即寻址 立即寻址也叫立即数寻址 这是一种特殊的寻址方式 操作数本身就在指令中给出 只要取出指令也就取到了操作数 这个操作数被称为立即数 对应的寻址方式也就叫做立即寻址 例如以下指令 ADDR0 R0 1 R0 R0 1 ADDR0 R0 0 x3f R0 R0 0 x3f 立即数 要求以 为前缀 对于以十六进制表示的立即数 还要求在 后加上 0 x 对于以二进制表示的立即数 还要求在 后加上 0b 对于以十进制表示的立即数 还要求在 后加上 0d 或者缺省 立即数的表示 1 8位立即数的表示8位立即数用 数字直接表示 2 32位立即数的表示由于32位立即数在指令中占用32个位 如果直接表示 则将导致ARM指令编码的长度超过32位 为了减小编码长度 32位立即数采用移位间接表示法 所谓移位间接表示法就是当指令中操作数为32位立即数时 该立即数必须采用一个8位常数然后通过偶数次的循环右移得到 这时候 假设这个立即数immediate 8位常数位immed 8 循环移位位数为2 rotate imm 那么 这个立即数可以表示成 immediate immed 8循环右移 2 rotate imm 采用移位间接表示时 在指令里面 这个32位的立即数immediate就可以用一个12位的编码 4位rotate imm 8位immed 8 来表示 如 MOVR0 0 x0000F200 编码为 E3A00CF2MOVR1 0 x00110000 编码为 E3A01811MOVR4 0 x00012800 编码为 E3A04B4A 0 x00012800 ob00010010100000000000这种编码算法的缺点是 并不是每一个32位常数都是一个合法的立即数 只有通过上述构造方法能够得到的32位立即数才是合法的立即数 如 0 x0000F200 0 x00110000 0 x00012800都是合法的立即数 而0 x1010 0 x00102或0FF1000等都不是合法的立即数 0 x0001010 ob0001000000010000 0 x0000102 ob0000000100000010 0 xFF1000 ob111111110001000000000000 TMD19有效立即数问题 3 2 2寄存器寻址 寄存器寻址就是利用寄存器中的数值作为操作数 这种寻址方式是各类微处理器经常采用的一种方式 也是一种执行效率较高的寻址方式 以下指令 ADDR0 R1 R2 R0 R1 R2 该指令的执行效果是将寄存器R1和R2的内容相加 其结果存放在寄存器R0中 TMD21寄存器为第2操作数的移位操作 当ARM指令的数据处理指令中参与操作的第2操作数为寄存器型时 可选择是否对该操作数进行移位操作 即 Rm 其中 Rm为第2操作数寄存器 为移位类型 LSL LSR ASL ASR ROR或RRX 和移位位数 移位位数可以是5位立即数或寄存器 Rs 在指令执行时 移位后的数作为第2操作数参与运算 如 ADDR3 R2 R1 LSR 2 R3 R2 R1 4ADDR3 R2 R1 LSRR4 R3 R2 R1 2R4而第2操作数寄存器的内容并不发生变化 另外 只有寄存器作为第2操作数时 才能进行这样的移位 否则 不允许进行这样的移位 第2操作数的移位方式 ARM可执行的移位操作有 LSL 逻辑左移 空出的最低位填0LSR 逻辑右移 空出的最高位填0ASL 算术左移 空出的最低位填0ASR 算术右移 如果被移位的数是有符号数 则空出的最高位填符号位 ROR 循环右移 移出的最低位填入空出的最高位RRX 带扩展的循环右移 右移一位 空出最高位填C 移出最低位进C 这种移位方式无需指定移位位数 3 2 3寄存器间接寻址 寄存器间接寻址就是以寄存器中的值作为操作数的地址 而操作数本身存放在存储器中 例如以下指令 LDRR0 R1 R0 R1 STRR0 R1 R1 R0 第一条指令将以R1的值为地址的存储器中的数据传送到R0中 第二条指令将R0的值传送到以R1的值为地址的存储器中 ARM的数据传送指令都是基于寄存器间接寻址 即通过Load Store完成对数据的传送操作 3 2 4基址加偏址寻址 基址变址寻址就是将寄存器 该寄存器一般称作基址寄存器 的内容与指令中给出的地址偏移量 用12位表示 不超过4KB 相加 从而得到一个操作数的有效地址 变址寻址方式常用于访问某基地址附近的地址单元 变址寻址方式可以分为 前变址 Pre indexed 自动变址 Auto indexed 和后变址 Post indexed 1 前变址模式LDRR0 R1 4 R0 R1 4 2 自动变址模式LDRR0 R1 4 R0 R1 4 R1 R1 4 3 后变址模式LDRR0 R1 4 R0 R1 R1 R1 4 偏移地址 地址偏移除了可以是一个12位的立即数 还可以是另一个寄存器 并且在加到基址寄存器之前还可以先经过移位操作 如 LDRR0 R1 R2 R0 R1 R2 LDRR0 R1 R2 LSL 2 R0 R1 R2 4 传送数据类型 ARM处理器支持的传送数据类型可以是有符号和无符号的8位字节 16位半字 32位字 最高位表示符号位 正数为0 负数为1 对于字节操作 在指令中增加了字母B 对于半字 在指令中增加了字母H进行标识 默认是字操作 不加数据类型标识 如 LDRBR0 R1 R0 mem8 R1 加载8位字节数据到寄存器R0 零扩展到32位LDRHR1 R0 20 R0 mem16 R0 20 加载16位半字到寄存器R1 零扩展到32位这时 传送的地址可与任意字节 半字对齐 而不限于4字节对齐 TMD28 3 2 5堆栈寻址 堆栈是一种数据结构 按先进后出 FirstInLastOut FILO 的方式工作 使用一个称作堆栈指针 SP 的专用寄存器 R13 指示当前的操作位置 堆栈指针总是指向栈顶 当堆栈指针指向最后压入堆栈的数据时 称为满堆栈 FullStack 而当堆栈指针指向下一个将要放入数据的空位置时 称为空堆栈 EmptyStack 根据堆栈的生成方式 又可以分为递增堆栈 AscendingStack 和递减堆栈 DecendingStack 当堆栈由低地址向高地址生成时 称为递增堆栈 当堆栈由高地址向低地址生成时 称为递减堆栈 堆栈工作方式 这样就有四种类型的堆栈工作方式满递增堆栈 堆栈指针指向最后压入的数据 且由低地址向高地址生成 满递减堆栈 堆栈指针指向最后压入的数据 且由高地址向低地址生成 空递增堆栈 堆栈指针指向下一个将要放入数据的空位置 且由低地址向高地址生成 空递减堆栈 堆栈指针指向下一个将要放入数据的空位置 且由高地址向低地址生成 堆栈寻址的实现 1 在ARM指令中 堆栈寻址是通过Load Store指令来实现的 如 STMFDSP R1 R7 LR 将R1 R7 LR入栈LDMFDSP R1 R7 LR 数据出栈 放入R1 R7 LR 2 在Thumb指令中 堆栈寻址通过PUSH POP指令来实现 如 PUSH R1 R7 LR 将R1 R7 LR入栈POP R1 R7 PC 数据出栈 放入R1 R7 PC TMD31 3 2 6块拷贝寻址 块拷贝寻址是多寄存器传送指令LDM STM的寻址方式 通过一条指令可以把一个数据块加载到多个寄存器中 也可以把多个寄存器中的内容保存到存储器中 这种寻址方式中的寄存器可以是R0 R15这16个通用寄存器中的部分或全部 如 LDMIAR0 R1 R2 R3 R4 R1 R0 R2 R0 4 R3 R0 8 R4 R0 12 该指令的后缀IA表示在每次执行完加载 存储操作后 R0按字长度增加 因此 指令可将连续存储单元的值传送到R1 R4 LDM STM指令依据其后缀名 如 IA DB 的不同 其寻址的方式也有很大不同 这些后缀可以定义存储器地址的增长是向上还是向下 以及地址的增减与指令操作的先后顺序 即 操作先进行还是地址的增减先进行 这些后缀可以分成两大类 一类用于数据的存储与读取 这类后缀有 IA IB DA DB 另一类用于堆栈的操作 即压栈和出栈 这类后缀有 FD ED FA EA 这些后缀的含义是 IA IncrementAfter 操作完成后地址递增IB IncrementBefore 地址先增后完成操作DA DecrementAfter 操作完成后地址递减DB DecrementBefore 地址先减后完成操作FD FullDecrement 满递减堆栈ED EmptyDecrement 空递减堆栈FA FullAggrandizement 满递增堆栈EA EmptyAggrandizement 空递减堆栈 块拷贝寻址示例 例 分析下面两条指令的作用 并分析基址寄存器的变化有什么不同 LDMIAR0 R2 R9 STMIAR1 R2 R9 这两句的作用是将R0指向的连续8个存储单元的内容拷贝到R1指向的连续8个单元中去 这两句执行完毕后 R0的内容增加了32个字节 这是由于使用了自动变址符号 而R1的内容保持保持不变 注意 在堆栈操作中总是要指定自动变址 否则 以前保存的内容会因为堆栈寄存器的基址不变将在下一次堆栈操作时遭到破坏 3 2 7相对寻址 与基址变址寻址方式相类似 相对寻址以程序计数器PC的当前值为基地址 指令中的地址标号作为偏移量 将两者相加之后得到操作数的有效地址 以下程序段完成子程序的调用和返回 跳转指令BL采用了相对寻址方式 BLNEXT 跳转到子程序 NEXT处执行 NEXT MOVPC LR 从子程序返回 3 3ARM指令详细介绍 ARM指令集总体分为以下6类 数据处理指令 Load Store指令 程序状态寄存器与通用寄存器之间的传送指令 转移指令 异常中断指令 协处理器指令 本节以上面ARM指令集的分类方式按顺序分别对其进行详细介绍 ARM指令及功能描述 3 3 1数据处理指令 ARM的数据处理指令主要完成寄存器中数据的算术和逻辑运算操作 本节按以下内容组织 数据处理指令分类数据处理指令二进制编码数据处理指令表 一 数据处理指令 分类 数据处理指令根据指令实现处理功能可分为以下六类 数据传送指令 算术运算指令 逻辑运算指令 比较指令 测试指令 乘法指令 数据处理指令的特点 所有操作数都是32位宽 或来自寄存器或来自指令中的立即数 符号或0扩展 如果数据操作有结果 则结果为32位宽 放在一个寄存器中 有一个例外是长乘指令的结果是64位的 ARM数据处理指令中使用 3地址模式 即1个目的操作寄存器 1个源操作数寄存器和1个灵活的第2操作数 这个第2操作数可以使寄存器 移位后的寄存器或者立即数 如果第2操作数为寄存器Rm 它也可以进行移位 包括 逻辑移位 算术移位 循环移位 移位位数可以来自一5位立即数或也可以使一寄存器的内容 当然 这3个操作数也可以只用1个或者2个 甚至1个都不用 如测试指令TST TEQ等 数据处理指令的汇编格式 根据第2操作数的类型 其汇编格式分为以下2种 S Rd Rn S Rd Rn Rm 注意 R15 PC 作为一个特殊的寄存器PC 同时也可以作为一般寄存器使用 但是当R15作源操作数时 不能指定移位位数 另外 在3级流水线中真实PC是当前指令地址加8 当R15作为目的操作数时 该指令的功能相当于执行某种形式的转移指令 也常用来实现子程序返回 另外 当R15作目的寄存器且使用了后缀S 则在恢复PC的同时 自动将当前模式的SPSR拷贝到CPSR 完成对CPSR的恢复 这是实现异常返回的标准方式 由于用户和系统模式下 没有自己的SPSR 因此 在这两种模式下这种操作无效 但汇编时并不警告 二 数据处理指令的二进制编码 数据处理指令的二进制编码如下 三 数据处理指令 指令表 数据处理指令的详细列表如下 四 数据处理指令简介 1 ADD ADC SUB SBC RSB和RSC 用法 ADD和SUB是简单的加减运算ADC和SBC是带进位的加减运算RSB是反减 即用第2个操作数减第1个操作数 由于第2个操作数可选范围宽 所以这条指令常用 RSC是带进位的反减 若C为0 则结果减1 注意事项 若设置S位 则这些指令根据结果更新标志N Z C和V ADC SBC和RSC可用于多字算术运算 如下面两条语句完成64位加法 ADDSR4 R0 R2ADDCR5 R1 R3 2 AND ORR EOR和BIC 用法 AND完成按位 与 操作 常用于提取寄存器中的某些位 如 ANDR9 R2 0XFF00ORR完成按位 或 操作 常用于将寄存器中的某些位设置为1 如 ORREQR2 R0 R5EOR完成按位 异或 操作 常用于将寄存器中的某些位的值取反 如 EORR0 R0 R3 RORR6BIC用于将源操作数的各位与第2操作数中相应位的反码进行 与 操作 常用于将寄存器中的某些位设置为0 如 BICNESR8 R10 R0 RRX注意事项 若设置S位 则这些指令根据结果更新标志N Z 在计算第2操作数时更新标志C 不影响V标志 3 MOV和MVN 用法 MOV是将第2操作数的值拷贝到结果寄存器中 如 MOVR9 R2MOVSR0 R0 RORR6MVN 取反传送 它是把第2操作数的每一位取反 将得到的值送入结果寄存器 如 MVNNER0 0XFF00注意事项 若设置S位 则这些指令根据结果更新标志N Z 在计算第2操作数时更新标志C 不影响V标志 4 CMP和CMN 用法 CMP表示比较 用目的操作数减去源操作数 根据结果更新条件码标志 除了将结果丢弃外 CMP指令和SUBS指令完成的操作一样 如 CMPGTR13 R7 LSL 2CMN表示取反比较 将目的操作数和源操作数相加 根据结果更新条件码标志 除了结果丢弃外 CMN指令与ADDS指令完成的操作一样 如 CMNR0 6400注意事项 这些指令根据结果更新标志N Z C和V 但结果不放到任何寄存器中 5 TST和TEQ 用法 TST表示位测试 对第2个操作数进行位 与 操作 根据结果更新条件码标志 除了将结果丢弃外 TST指令和ANDS指令完成的操作一样 TST通常用于测试寄存器中某些位是1还是0 如 TSTR0 0 x3F8TEQ表示测试相等 对第2个操作数进行按位 异或 操作 根据结果更新条件码标志 除了结果丢弃外 TEQ指令与EORS指令完成的操作一样 TEQ通常用于比较2个操作数是否相等 这种比较一般不影响CPSR的V和C 它也可用于比较2个操作数符号是否相同 如 TEQEQR10 R9注意事项 这些指令根据结果更新标志N Z C和V 但结果不放到任何寄存器中 6 乘法指令 乘法指令完成2个寄存器中数据的乘法 按结果位宽一般分为2类 一类是2个32位二进制数相乘的结果是64位 另一类是2个32位二进制数相乘 仅保留最低有效32位 并且这2类指令都有乘加变形 即将乘积连续相加成为总和 而且有符号和无符号操作数都能使用 这两类指令共有6条 如下图所示 表3 4乘法指令 注 对于有符号和无符号操作数 结果的最低有效32位是一样的 所以对于只保留32位结果的乘法指令 无须区分有符号和无符号数2种格式 乘法指令的二进制编码 图3 5乘法指令的二进制编码 说明 对于32位乘积结果指令 Rd为结果寄存器 Rm Rs Rn为操作数寄存器 对于64位乘积结果指令 RdLo RdHi为结果寄存器 RdHi RdLo 是由RdHi 最高有效32位 和RdLo 最低有效32位 连接形成64位乘积结果 Rm Rs为操作数寄存器 R15不能用作Rd Rm Rs或Rn 且Rd不能与Rm相同 当在指令中设置了S后根据结果影响标志位N和Z 对于32位结果的指令 N为Rd的第31位值 对于产生64位结果的指令 N设置为RdHi的第31位值 如果Rd或RdHi和RdLo为0 则Z标志置位 ARMV4及以前版本标志C V不可靠 ARMV5后 不影响C和V 汇编格式 产生32位乘积的指令 MUL S Rd Rm RsMULA S Rd Rm Rs Rn产生64位乘积的指令 UMULL S RdHi RdLo Rm RsUMLAL S RdHi RdLo Rm RsSMULL S RdHi RdLo Rm RsSMLAL S RdHi RdLo Rm Rs例子 MOVR11 20 初始化循环计数器MOVR10 0 初始化总和LOOP LDRR0 R8 4 读取第1分量LDRR1 R9 4 读取第2分量MLAR10 R0 R1 R10 乘积累加SUBSR11 R11 1 循环减计数BNELOOP 乘以一个常数 可以先把常数放到寄存器中 然后再用上述指令实现 但是 有时利用移位和乘加指令组合构成一个程序段更有效 如 将R0乘以35可以如下实现ADDR0 R0 R0 LSL 2 R0 R0 5RSBR0 R0 R0 LSL 3 R0 R0 7注意事项 不支持第2操作数为立即数 结果寄存器不能同时作为第一源寄存器 即Rd RdHi和RdLo不能与Rm为同一寄存器 RdHi和RdLo不能为同一寄存器 应避免R15定义为任一操作数或结果操作数 早期的ARM处理器仅支持32位乘法指令 MUL和MLA ARM7版本 ARM7DM ARM7TM等 和后续的在名字中有M的处理器才支持64位乘法器 注意事项 3 3 2Load Store指令 ARM处理器是Load Store型的 即它对数据的操作是通过将数据从存储器加载到片内寄存器中进行处理 处理完成后的结果经过寄存器存回到存储器中 以加快对片外存储器进行数据处理的速度 ARM的数据存取指令Load Store是唯一用于寄存器和存储器之间进行数据传送的指令 在ARM系统中I O操作是通过存储器映射进行寻址的 对I O设备的操作可以和对存储器的操作一样 因此 也是使用Load Store指令完成 ARM指令集中有三种基本的数据存取指令 单寄存器的存取指令 LDR STR 提供寄存器和存储器之间最灵活的单数据项传送方式 传送的数据可以是8位字节 16位半字或32位字 多寄存器存取指令 LDM STM 可有效地用于大批数据的传送 一般这些指令用于进程的进入和退出 保存和恢复工作寄存器以及拷贝存储器中一块数据 单寄存器交换指令 SWP 用于寄存器和存储器中的数据交换 在一个指令中完成存取操作 该指令常用来完成信号量操作 而信号量是一种解决进程同步和互斥问题的机制 Load Store指令分类 一 单寄存器的存取指令 单寄存器存取指令是ARM在寄存器和存储器间传送单个字节和字的最灵活方式 根据传送数据的类型不同 单个寄存器存取指令又可以分为以下两类 单字和无符号字节的数据传送指令半字和有符号字节的数据传送指令 1 单字和无符号字节的数据传送指令 这一类数据传送指令的编码格式如下 单字和无符号字节数据传送指令的二进制编码 基址寄存器加上或减去一个无符号立即数或者寄存器偏移量构成存储器访问地址 当从存储器读取一个无符号字节数据时 需要将它用0扩展到32位 然后放置到目的寄存器中 当从一个寄存器向存储器写一个字节的数据时 写的是寄存器的低8位 前变址的寻址模式使用计算出的地址作为存储器地址进行数据存取操作 然后 当要求回写 W 1 将基址寄存器更新为计算出的地址值 后变址的寻址模式用未修改的基址寄存器来传送数据 然后将基址寄存器更新为计算出的地址 而不管W位如何 指令说明 前变址格式LDR STR B Rd Rn 其中B表示是按字节传送 缺省时按字传送 offset可能是 12位立即数 或者 Rm 这里shift包括移位方式和移位位数 移位位数只能是5位立即数 而不能再来自于寄存器Rs 根据有无 选择是否回写 自动变址 后变址格式LDR STR B T Rd Rn 其中T标志只能在非用户模式 即特权模式 下使用 作用是选择用户角度的存储器访问 相对PC的形式LDR STR B Rd LABEL 指令汇编格式 LDRR8 R10 R8 R10 LDRNER1 R5 960 有条件地 R1 R5 960 R5 R5 960STRR2 R9 consta struc consta struc是常量表达式 范围为 4095 4095STRBR0 R3 R8 ASR 2 R0 R3 R8 4 存储R0的最低有效字节 但R3和R8的内容不变LDRR1 localdata 加载一个字 该字位于标号localdata所在地址 相对PC形式 LDRR0 R1 R2 LSL 2 将地址为R1的内存单元数据读取到R0中 然后R1 R1 R2 4LDRBR0 R2 3 将内存单元 R2 3 中的字节数据读到R0中 R0的高24位被设置为0LDRR1 R0 R2 LSL 2 将R0 R2 4地址处的数据读出 保存到R1中 R0 R2的值保持不变 STRR0 R7 8 将R0的内容存到R7中地址对应的内存中 R7 R7 8 举例 在编程中 常使用相对PC的形式将R0中的一个字存到外设UART 如 LDRR1 UARTADDSTRR0 R1 或者 使用相对PC形式将外设UART数据读到R0 如 LDRR1 UARTADDLDRR0 R1 注意 这里UARTADD标号在附近4KB范围之内 使用PC作为基址时 得到的传送地址为当前指令地址加8字节 PC不能用作偏移寄存器 也不能用于任何自动变址寻址模式 包括后变址模式 把一个字读到PC可以使程序转移到读取的地址 从而实现程序跳转 但应避免将一个字节读取到PC 应尽量避免把PC存储到存储器 因为不同处理器可能会产生不同的结果 只要不使用自动变址 Rd Rn是可以的 但在一般情况下 Rd Rn和Rm应是不同的 2 半字和有符号字节的数据传送指令 有符号的字节或半字的传送用 符号位 扩展到32位 无符号半字的传送用0扩展到32位 这类数据传送的二进制编码如下 立即数偏移量只能8位之内 寄存器偏移量不可移位得到 S H用于定义所传送的数据类型 这一类数据传送指令的汇编格式如下 前变址格式LDR STR H SH SBRd Rn 后变址格式LDR STR H SH SBRd Rn 式中是 或 Rm H SH SB选择传送数据类型 其它部分的汇编器格式与传送字和无符号字节相同 所有半字传送应使用半字对齐的地址 指令汇编格式 LDREQSHR11 R6 有条件地 R11 R6 加载16位半字 有符号扩展到32位LDRHR1 R0 20 R1 R0 20 加载16位半字 0扩展到32位STRHR4 R3 R2 R4 R3 R2 存储最低的有效半字到R3 R2LDRSBR0 const 加载位于标号const地址的字节 有符号扩展LDRHR6 R2 2 将R2地址上的半字数据读出到R6 高16位用0扩展 R2 R2 2LDRSHR1 R9 将R9地址上的半字数据读取到R1中 高16位用符号位扩展STRHR0 R1 R2 LSL 2 将R0的内容送到 R1 R2 4 对应的内存中STRNEHR0 R2 960 有条件地 将R0的内容送到 R2 960 的内存中 R2 R2 960 举例 二 多寄存器存取指令 多寄存器传送指令可以用一条指令将16个可见寄存器 R0 R15 的任意子集合 或全部 存储到存储器或从存储器中读取数据到该寄存器集合中 如 可将寄存器列表保存到堆栈 也可将寄存器列表从堆栈中恢复 这种指令有两个特殊用法 1 允许操作系统加载或存储用户模式寄存器来保护或恢复用户处理状态 2 作为异常处理返回的一部分 完成从SPSR中恢复CPSR 这种指令与单寄存器存取指令相比 多寄存器数据存取可用的寻址模式更加有限 多寄存器存取指令的二进制编码如下 二进制编码的低16位对应R15 R0的寄存器列表 存储器地址可以通过基址寄存器Rn和寻址模式的定义来实现 在传送一个字前或后基址将增加或减少 如果W 1 则支持自动变址 则当指令完成时 基址寄存器将增加或减少所传送的字节数 多寄存器存取指令的二进制编码如下 S位是该指令的特殊用法 如果PC在读取多寄存器的寄存器列表中 且S位置位 则当前模式的SPSR将被拷贝到CPSR 但这种指令不能用在用户模式下 因为用户模式下没有SPSR 如果PC不在寄存器列表中且S位置位 在非用户模式下 执行读取和存入多寄存器指令将传送用户模式下寄存器 虽然使用的是当前模式的基址寄存器 这使得操作系统可以保存和恢复用户处理状态 LDM STM Rn 这里指定一种寻址模式 表明地址的变化是操作前还是执行后 是在基址基础上增加还是减少 表示是自动变址 W 1 是寄存器列表 用大括号将寄存器组括起来 列表中的寄存器的次序是不重要的 它不影响存取的次序和指令执行后寄存器的值 因为这里有个约定 编号低的寄存器在存储数据或者加载数据时 对应于存储器的低地址 也就是说 编号最低的寄存器保存到最低地址 或从最低地址取数 其他依次递增 指令汇编格式 LDMIAR1 R0 R2 R5 R0 mem32 R1 R2 mem32 R1 4 R5 mem32 R1 8 STMDBR1 R3 R6 R11 R12 R12 mem32 R1 4 R11 mem32 R1 8 R6 mem32 R1 12 R5 mem32 R1 16 R4 mem32 R1 20 R3 mem32 R1 24 R1 R1 24STMEDSP R0 R7 LR 现场保存 将R0 R7 LR入栈 R14 mem32 R13 R7 mem32 R13 4 R0 mem32 R13 36 R13 R13 36 举例 如果在保存多寄存器指令的寄存器列表中指定了PC 则保存的值与体系结构实现方式有关 因此 一般应避免在STM指令中指定PC 如果在读取或存入多寄存器指令的传送列表中包含基址寄存器 则在该指令中不能使用回写模式 因为这样做的结果是不可预测的 如果基址寄存器包含的地址不是字对齐的 则忽略最低2位 一些ARM系统则可能产生异常 注意事项 三 存储器与寄存器交换指令 SWP 其二进制编码格式如下 其汇编格式如下 SWP B Rd Rm Rn 本指令将存储器中地址为Rn处的字 B 0 或无符号字节 B 1 读入寄存器Rd 同时 将Rm中同样类型的数据存入存储器中相同的位置 Rd和Rm可以相同 但与Rn应该不同 另外 PC不能出现在该指令中 交换指令把字或无符号字节的读取和存储组合在了一条指令中 这种组合指令通常用于不能被外部其他存储器访问 如 DMA访问 打断的存储器操作 一般用于处理器之间或处理器与DMA控制器之间共享信息的互斥访问 LDRR0 SEMAPHORESWPBR1 R1 R0 交换字节 将存储器单元 R0 中的字节数据读取到R1种 同时 将R1种的数据写入到存储器单元 R0 中SWPR1 R2 R3 交换字数据 将存储单元 R3 中的字数据读取到R1中 同时 将R2中的数据写入到存储单元 R3 中 举例 3 3 3状态寄存器与通用寄存器之间的传送指令 ARM指令中有两条指令 用于在状态寄存器和通用寄存器之间传送数据 修改状态寄存器一般是通过 读取 修改 写回 三个步骤的操作来实现的 这两条指令分别是 状态寄存器到通用寄存器的传送指令 MRS 通用寄存器到状态寄存器的传送指令 MSR 一 MRS MRS指令用于将状态寄存器的内容传送到通用寄存器中 它主要用于以下3种场合 1 通过 读 修改 写 修改状态寄存器的内容 MRS用于将状态寄存器的内容读到通用寄存器中 以便修改 2 当异常中断允许嵌套时 需要在进入异常中断后 嵌套中断发生之前 保存当前处理器模式的SPSR 这是需要先通过MRS指令读出SPSR的值 然后用其他指令将SPSR的值保存起来 3 当进程切换时 也需要保存当前寄存器的值 MRS的二进制编码如下 这里R用来区分是将CPSR还是SPSR拷贝到目的寄存器Rd 全部32位都被拷贝 其汇编格式如下 MRS Rd CPSR SPSR举例 MRSR0 CPSR 将CPSR传送到R0MRSR3 SPSR 将SPSR传送到R3 不能通过该指令修改CPSR中的T控制位 直接将程序状态切换到Thumb状态 必须通过BX等指令实现程序状态切换 在用户或系统模式下没有可以访问的SPSR 所以SPSR形式在这些模式下不能用 当修改CPSR或SPSR时 必须注意保存所有未使用位的值 这条指令不影响条件标志码 注意事项 二 MSR MSR的二进制编码如下 操作数可以是一个寄存器Rm也可以是带循环移位的8位有效立即数 在域屏蔽的控制下传送到CPSR或SPSR 域屏蔽控制PSR中4字节的更新 其中第16位控制PSR 7 0 是否更新 第17位控制PSR 15 8 第18位控制PSR 23 16 第19位控制PSR 31 24 使用立即数时 只有PSR 31 24 可选择 其汇编格式如下 MSR CPSR f SPSR f MSR CPSR SPSR Rm 这里的表示下列情况之一 c 控制域 对应PSR 7 0 x 扩展域 对应PSR 15 8 在当前ARM中未使用 s 状态域 对应PSR 23 16 在当前ARM中未使用 f 标志位域 对应PSR 31 24 举例 1 设置N Z C和V标志位MSRCPSR f 0 xF0000000 设置所有标志位 2 仅设置C标志位 保存N Z和VMRSR0 CPSR 将CPSR传送到R0ORRR0 R0 0 x200000000 设置R0的第29位MSRCPSR f R0 传送回CPSR 3 从监控模式切换到IRQ模式MRSR0 CPSR 将CPSR传送到R0BICR0 R0 0 x1F 低5位清0ORRR0 R0 0 x12 设置为IRQ模式MSRCPSR c R0 传送回CPSR 在用户模式下不能对CPSR 23 0 做任何修改 在用户或系统模式下没有SPSR 所以应尽量避免在这些模式下访问SPSR 在嵌套的异常中断处理中 当退出中断处理程序时 通常通过MSR指令将事先保存了的SPSR内容恢复到当前程序状态寄存器CPSR中 在修改的状态寄存器位域中包括未分配的位时 避免使用立即数方式的MSR指令 不能通过该指令直接修改CPSR中的T控制位直接将程序状态切换到Thumb状态 必须通过BX等指令来完成程序状态的切换 注意事项 3 3 4转移指令 ARM有2种方法可实现程序的转移 一种是利用传送指令直接向PC寄存器R15中写入转移的目标地址 通过改变PC的值实现程序的转移 另一种就是利用转移指令 ARM的转移指令可以从当前指令向前或向后的32MB的地址空间跳转 根据完成的功能它可以分为以下4种 B转移指令BL带链接的转移指令BX带状态切换的转移指令BLX带链接和状态切换的转移指令 一 转移和转移链接指令 B BL 转移指令B在程序中完成简单的跳转指令 可以跳转到指令中指定的目的地址 BL指令完全象转移指令一样地执行转移 同时把转移后面紧接的一条指令的地址保存到链接寄存器LR r14 这样可以实现子程序的返回 二进制编码如下 跳转目标地址的计算方法 先对指令中定义的有符号的24位转移量用符号扩展为32位 并将该32位左移2位形成字的偏移 然后将它加到程序计数器PC中 相加前程序计数器的内容为转移指令地址加8字节 一般情况下汇编器将会计算正确的偏移 转移范围为 32MB L标志为1时 为转移连接指令 汇编格式如下 B L L指定转移与连接属性 如果不包括L 便产生没有连接的转移 是条件执行的助记符扩展 缺省为AL 即无条件转移 一般是汇编代码中的标号 是转移到的目标地址 举例 1 无条件转移BLABEL 无条件跳转 LABEL 举例 2 执行10次循环MOVR0 10 初始化循环计数器LOOP SUBSR0 R0 1 计数器减1 设置条件码BNELOOP 如果计数器R0 0 重复循环 3 调用子程序 BLSUB 转移连接到子程序SUB 返回到这里SUB 子程序入口MOVPC R14 返回注意 在子程序返回之前 不应再调用下一级嵌套子程序 TMD89汇编语言子程序调用及返回 在ARM汇编语言中 子程序调用是通过BL指令来完成的 BL指令的语法格式如下 BLsubname其中 subname是被调用的子程序的名称 BL指令完成两个操作 将子程序的返回地址放在LR寄存器 r14 中 同时将PC寄存器值设置成目标子程序的第一条指令地址 在返回调用子程序时 转移链接指令保存到LR寄存器 r14 中的值需要拷贝回程序寄存器PC r15 举例 4 子程序的嵌套调用为了实现子程序的嵌套调用 应该在调用嵌套子程序之前 先将R14内容压栈保存 如 BLSUB1 转移连接到子程序SUB1 返回到这里SUB1 子程序1入口STMFDSP R14 BLSUB2LTMFDSP R14 MOVPC R14 返回SUB2 子程序入口2 举例 5 条件子程序调用 CMPR0 5 如果R0 5BLLTSUB1 然后调用SUB1BLGESUB2 否则调用SUB2 注意 只有SUB1不改变条件 这里才能正常运行 注意事项 当转移指令转移到32MB地址空间之外时 将产生不可预测的结果 二 转移交换和转移链接交换 BX BLX 这些指令用于支持Thumb 16位 指令集的ARM芯片 程序可以通过这些指令完成处理器从ARM状态到Thumb状态的切换 类似的Thumb指令可以使处理器切换回32位ARM指令 在第一种格式中 寄存器Rm的值是转移目标 Rm的第0位拷贝到CPSR中的T位 进而决定是切换到Thumb状态还是ARM状态 31 1 位移入PC 如果Rm 0 是1 则切换到Thumb状态 并在Rm中的地址处开始执行 但需将最低位清0 使之半字对齐 如果Rm 0 是0 则切换到ARM状态 并在Rm中的地址处开始执行 但需将Rm 1 清0 使之半字对齐 ARM的状态寄存器CPSR中的状态控制位T bit 位 5 决定了当前处理器的运行状态 因此 可以通过MSR和MRS指令来直接修改CPSR的状态位 也能够改变处理器运行状态但由于ARM采用多级流水线的结构 这样做会造成流水线上预取指令的执行错误 而如果用BX指令 则不会出现这样的问题 下面是一段直接进行状态切换的例程 从ARM状态开始CODE32 表明以下是ARM指令ADRR0 Into Thumb 1 得到目标地址 末位置1 表示转移到ThumbBXR0 转向Thumb 执行其它代码CODE16 表明以下是Thumb指令Into Thumb Thumb代码ADRR5 Back to ARM 得到目标地址 末位缺省为0 转移到ARMBXR5 转向ARM 执行其它代码CODE32 表明以下是ARM指令Back to ARM ARM代码段起始地址 3 3 5异常中断产生指令 异常中断指令可以分为一下两种 软件中断指令 SWI 断点指令 BKPT 仅用于v5T体系 软件中断指令SWI用于产生SWI异常中断 用来实现在用户模式下对操作系统中特权模式的程序的调用 断点中断指令BKPT主要用于产生软件断点 供调试程序用 一 SWI SWI SoftWareInterrupt 代表 软件中断 用于用户调用操作系统的系统例程 常称为 监控调用 它将处理器置于监控 SVC 模式 从地址0 x08开始执行指令 其二进制编码如下 SWI指令用于产生软件中断 以便用户程序能调用操作系统的系统例程 操作系统在SWI的异常处理程序中提供相应的系统服务 指令中24位的立即数指定用户程序调用系统例程的类型 相关参数通过通用寄存器传递 当指令中24位的立即数被忽略时 用户程序调用系统例程的类型由通用寄存器R0的内容决定 同时 参数通过其他通用寄存器传递 例如 MOVR0 A 将 A 调入到R0中 SWISWI WriteC 打印它 如果条件通过 则指令使用标准的ARM异常入口程序进入监控 SVC 程序 管理模式 这时处理器的行为是 将SWI后面指令的地址保存到R14 svc 将CPSR保存到SPSR svc 进入监控模式 将CPSR 4 0 设置为0b10011和将CPSR 7 设置为1 以便禁止IRQ 但不是FIQ 将PC设置为0 x08 并且从这里开始执行指令 汇编格式如下 SWI 二 断点指令 BKPT 仅用于v5T体系 断点指令用于软件调试 它使处理器停止执行正常指令 使处理器中止预取指 而进入相应的调试程序 其二进制编码如下 汇编格式如下 BKPT immed 16 注 immed 16为表达式 其值为0 65536 该立即数被调试软件用来保存额外的端点信息 另外 该指令是无条件的 并且V5T体系结构的微处理器才支持BKPT 举例 BKPT BKPT0 xF02C 三 前导0计数 前导0计数 CLZ 仅用于V5T体系 用来实现数字归一化 其二进制编码如下 说明 本指令将Rd设置为Rm中为1的最高有效位的位置数 即对Rm中的前导0的个数进行计数 并将计数结果放到Rd中 汇编格式如下 CLZ Rd Rm注 Rd不允许是R15 PC 举例 MOVR2 0 x17F00CLZR3 R2 R3 15 3 3 6协处理器
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025福建南平市山点水园林有限公司招聘及拟进入考前自测高频考点模拟试题及答案详解1套
- 2025贵州都匀市直部门(含所属事业单位)考调工作人员35人考前自测高频考点模拟试题有答案详解
- 2025北京儿童医院顺义妇儿医院招聘编制外6人考前自测高频考点模拟试题参考答案详解
- 可拉伸光电传感技术-洞察与解读
- 2025年河南红旗渠(集团)有限责任公司招聘7人考前自测高频考点模拟试题及1套参考答案详解
- 2025广东工程职业技术学院招聘事业编制人员(辅导员)5人模拟试卷含答案详解
- 纺织品绿色供应链竞争力-洞察与解读
- 2025年临沂郯城县技工学校公开招聘教师(26人)模拟试卷完整答案详解
- 代码模块化设计-第2篇-洞察与解读
- 2025湖南怀化市靖州苗族侗族自治县政务服务中心见习人员招聘1人模拟试卷有答案详解
- 2025年安徽萧县县直事业单位招聘115人笔试备考题库附答案详解
- 风险分级管控和隐患排查治理体系培训考试试题(附答案)
- 迷彩施工方案
- 2025大模型背景下高等教育数智化转型研究报告
- 2025汽车驾驶员(技师)考试题及答案
- 2025事业单位联考A类《综合应用能力》模拟试题(含答案)
- 水路危险货物运输员专项考核试卷及答案
- 多传感器融合赋能无人驾驶列车的安全感知-洞察及研究
- 汉字的六种结构方式
- 2026年高考数学一轮复习三维设计创新-微拓展 圆锥曲线中的二级结论
- 口腔补牙课件
评论
0/150
提交评论