常用 ARM 指令集及汇编 2003 年 12 月 1 日
前 言 ARM(Advanced RISC Machines) 是 微 处 理 器 行 业 的 一 家 知 名 企 业, 该 企 业 设 计 了 大 量 高 性 能 廉 价 耗 能 低 的 RISC 处 理 器 相 关 技 术 及 软 件 技 术 具 有 性 能 高 成 本 低 和 能 耗 省 的 特 点, 适 用 于 多 种 领 域, 比 如 嵌 入 控 制 消 费 / 教 育 类 多 媒 体 DSP 和 移 动 式 应 用 等 ARM 将 其 技 术 授 权 给 世 界 上 许 多 著 名 的 半 导 体 软 件 和 OEM 厂 商, 每 个 厂 商 得 到 的 都 是 独 一 无 二 的 ARM 相 关 技 术 及 服 务, 利 用 这 种 合 作 关 系,ARM 很 快 成 为 许 多 全 球 性 RISC 标 准 的 缔 造 者 目 前,ARM 内 核 的 微 处 理 器 正 在 我 国 迅 速 普 及 和 发 展, 许 多 朋 友 已 经 开 始 着 手 学 习 研 究 和 利 用 这 类 芯 片 进 行 商 品 化 设 计, 为 了 帮 助 广 大 朋 友 更 快 的 学 习 和 使 用 这 种 先 进 的 技 术, 广 州 周 立 功 单 片 机 发 展 有 限 公 司 (http://www.zlgmcu.com) 曾 面 向 大 众 推 出 了 一 款 EasyARM 试 验 板, 本 文 的 大 部 分 内 容 来 自 此 款 试 验 板 的 配 套 教 材 -- ARM 微 控 制 器 基 础, 并 且 得 到 周 立 功 正 式 授 权 本 文 主 要 是 针 对 ARM7TDMI(-S) 内 核, 经 本 人 重 新 排 版, 制 作 成 PDF 格 式, 便 于 大 家 查 阅 和 使 用 本 文 仅 仅 用 于 大 家 的 学 习 和 研 究 使 用, 由 于 本 文 的 原 因 造 成 元 器 件 的 损 坏 设 计 方 案 的 缺 陷 与 失 败 等 一 切 损 失, 概 不 负 责 感 谢 周 立 功 老 师 为 我 们 提 供 了 丰 富 的 资 源 并 亲 自 审 阅 了 本 文, 感 谢 单 片 机 学 习 网 (http://www.mcustudy.com) 为 我 们 提 供 了 交 流 和 学 习 的 空 间, 感 谢 我 的 女 友 对 我 这 项 工 作 的 支 持, 她 自 己 放 弃 了 大 量 的 业 余 时 间 帮 我 录 入 和 排 版 由 于 时 间 仓 促, 本 文 难 免 会 存 在 不 当 之 处, 欢 迎 大 家 来 信 (email:mcu8031@163.com) 或 在 网 上 (QQ:57523799) 批 评 指 正 和 交 流, 以 便 在 今 后 的 版 本 加 以 更 正, 也 希 望 大 家 能 把 自 己 在 工 作 中 的 心 得 体 会 和 经 验 拿 出 来, 和 众 多 的 同 行 及 爱 好 者 交 流, 共 同 提 高, 一 起 进 步 宛 城 布 衣 2003 年 12 月 1 日 星 期 一 第 i 页
目 录 前 言...i 目 录...I ARM7TDMI(-S) 指 令 集 及 汇 编...1 ARM 处 理 器 寻 址 方 式...2 寄 存 器 寻 址...2 立 即 寻 址...2 寄 存 器 偏 移 寻 址...2 寄 存 器 间 接 寻 址...3 基 址 寻 址...3 多 寄 存 器 寻 址...4 堆 栈 寻 址...4 块 拷 贝 寻 址...5 相 对 寻 址...5 指 令 集 介 绍...7 ARM 指 令 集...7 指 令 格 式...7 第 2 个 操 作 数...7 #immed_8r...7 Rm...8 Rm,shift...8 条 件 码...9 ARM 存 储 器 访 问 指 令... 11 LDR 和 STR... 11 LDM 和 STM...14 SWP...17 ARM 数 据 处 理 指 令...19 数 据 传 送 指 令...20 MOV...20 MVN...20 算 术 逻 辑 运 算 指 令...20 ADD...20 SUB...21 RSB...21 ADC...21 SBC...21 RSC...22 AND...22 ORR...22 EOR...22 BIC...23 第 I 页
比 较 指 令...23 CMP...23 CMN...23 TST...24 TEQ...24 乘 法 指 令...25 MUL...25 MLA...25 UMULL...25 UMLAL...26 SMULL...26 SMLAL...26 ARM 跳 转 指 令...27 B...27 BL...27 BX...27 ARM 协 处 理 器 指 令...28 CDP...28 LDC...29 STC...29 MCR...30 MRC...30 ARM 杂 项 指 令...31 SWI...31 MRS...32 MSR...33 ARM 伪 指 令...34 ADR...35 ADRL...35 LDR...36 NOP...37 Thumb 指 令 集...39 Thumb 指 令 集 与 ARM 指 令 集 的 区 别...39 Thumb 存 储 器 访 问 指 令...40 LDR 和 STR...41 PUSH 和 POP...43 LDMIA 和 STMIA...43 Thumb 数 据 处 理 指 令...45 数 据 传 送 指 令...46 MOV...46 MVN...46 NEG...47 算 术 逻 辑 运 算 指 令...47 ADD...47 第 II 页
SUB...48 ADC...49 SBC...49 MUL...50 AND...50 ORR...50 EOR...51 BIC...51 ASR...51 LSL...52 LSR...52 ROR...53 比 较 指 令...53 CMP...53 CMN...54 TST...54 Thumb 跳 转 指 令...55 B...55 BL...55 BX...55 Thumb 杂 项 指 令...56 SWI...56 Thumb 伪 指 令...57 ADR...57 LDR...57 NOP...58 伪 指 令...59 符 号 定 义 伪 指 令...59 GBLA GBLL GBLS...59 LCLA LCLL LCLS...60 SETA SETL SETS...61 RLIST...61 CN...62 CP...62 DN SN...62 FN...63 数 据 定 义 伪 指 令...63 LTORG...64 MAP...64 FIELD...65 SPACE...66 DCB...66 DCD 和 DCDU...67 DCDO...67 第 III 页
DCFD 和 DCFDU...68 DCFS 和 DCFSU...68 DCI...69 DCQ 和 DCQU...69 DCW 和 DCWU...70 报 告 伪 指 令...70 ASSERT...70 INFO...71 OPT...71 TTL 和 SUBT...72 汇 编 控 制 伪 指 令...73 IF ELSE 和 ENDIF...73 MACRO 和 MEND...74 WHIL 和 WEND...75 杂 项 伪 指 令...76 ALIGN...77 AREA...78 CODE16 和 CODE32...79 END...80 ENTRY...80 EQU...81 EXPORT 和 GLOBAL...81 IMPORT 和 EXTERN...82 GET 和 INCLUDE...83 INCBIN...83 KEEP...83 NOFP...84 REQUIRE...84 PEQUIRE8 和 PRESERVE8...84 RN...84 ROUT...85 ARM 伪 指 令...86 ADR...86 ADRL...86 LDR...86 NOP...86 LDFD...86 LDFS...87 Thumb 伪 指 令...87 ADR...87 LDR...87 NOP...88 ARM 汇 编 程 序 设 计...88 文 件 格 式...88 第 IV 页
ARM 汇 编 的 一 些 规 范...88 汇 编 语 句 格 式...88 标 号...89 基 于 PC 的 标 号...89 基 于 寄 存 器 的 标 号...90 绝 对 地 址...90 局 部 标 号...90 符 号...91 常 量...91 数 字 常 数...91 字 符 常 量...92 布 尔 常 量...92 段 定 义...92 宏 定 义 及 其 作 用...93 子 程 序 的 调 用...94 数 据 比 较 跳 转...95 循 环...95 数 据 块 复 制...95 栈 操 作...96 特 殊 寄 存 器 定 义 及 应 用...96 散 转 功 能...97 查 表 操 作...97 长 跳 转...97 对 信 号 量 的 支 持...98 伪 指 令 使 用...98 一 个 完 整 的 例 子...98 外 围 部 件 控 制...99 三 级 流 水 线 介 绍...99 C 与 汇 编 混 合 编 程...100 内 嵌 汇 编...100 内 嵌 汇 编 的 指 令 用 法...103 内 嵌 汇 编 器 与 armasm 汇 编 器 的 差 异...104 内 嵌 汇 编 注 意 事 项...104 访 问 全 局 变 量...106 C 与 汇 编 相 互 调 用...107 寄 存 器 的 使 用 规 则...108 堆 栈 使 用 规 则...108 参 数 传 递 规 则...109 C 程 序 调 用 汇 编 程 序... 110 汇 编 程 序 调 用 C 程 序... 111 ARM 指 令 集 列 表... 113 ARM 存 储 器 访 问 指 令 表 列 表... 113 ARM 数 据 处 理 指 令 列 表... 114 ARM 乘 法 指 令 列 表... 115 第 V 页
ARM 跳 转 指 令 列 表... 116 ARM 协 处 理 器 指 令 列 表... 117 ARM 杂 项 指 令 列 表... 118 ARM 伪 指 令 列 表... 119 Thumb 指 令 集 列 表...120 Thumb 存 储 器 访 问 指 令 列 表...120 Thumb 数 据 处 理 指 令 列 表...121 Thumb 跳 转 指 令 及 软 中 断 指 令 列 表...122 Thumb 伪 指 令 列 表...123 汇 编 预 定 义 变 量 及 伪 指 令...124 预 定 义 的 寄 存 器 和 协 处 理 器 名...124 通 用 寄 存 器...124 程 序 状 态 寄 存 器...124 浮 点 数 寄 存 器...124 协 处 理 器 及 协 处 理 器 寄 存 器...125 内 置 变 量 列 表...125 伪 指 令 列 表...126 指 令 条 件 码 列 表...128 CPSR 和 SPSR 分 配 图...129 第 VI 页
ARM7TDMI(-S) 指 令 集 及 汇 编 ARM 处 理 器 是 基 于 精 简 指 令 集 计 算 机 (RISC) 原 理 设 计 的, 指 令 集 和 相 关 译 码 机 制 较 为 简 单,ARM7TDMI(-S) 具 有 32 位 ARM 指 令 集 和 16 位 Thumb 指 令 集,ARM 指 令 集 效 率 高, 但 是 代 码 密 度 低, 而 Thumb 指 令 集 具 有 更 好 的 代 码 密 度, 却 仍 然 保 持 ARM 的 大 多 数 性 能 上 的 优 势, 它 是 ARM 指 令 集 的 子 集 所 有 ARM 指 令 都 是 可 以 有 条 件 执 行 的, 而 Thumb 指 令 仅 有 一 条 指 令 具 备 条 件 执 行 功 能 ARM 程 序 和 Thumb 程 序 可 相 互 调 用, 相 互 之 间 的 状 态 切 换 开 销 几 乎 为 零 第 1 页
ARM 处 理 器 寻 址 方 式 寻 址 方 式 是 根 据 指 令 中 给 出 的 地 址 码 字 段 来 实 现 寻 找 真 实 操 作 数 地 址 的 方 式,ARM 处 理 器 有 9 种 基 本 寻 址 方 式 寄 存 器 寻 址 操 作 数 的 值 在 寄 存 器 中, 指 令 中 的 地 址 码 字 段 指 出 的 是 寄 存 器 编 号, 指 令 执 行 时 直 接 取 出 寄 存 器 值 操 作 寄 存 器 寻 址 指 令 举 例 如 下 : MOV R1,R2 ;R2 -> R1 SUB R0,R1,R2 ;R1 - R2 -> R0 立 即 寻 址 立 即 寻 址 指 令 中 的 操 作 码 字 段 后 面 的 地 址 码 部 分 就 是 操 作 数 本 身, 也 就 是 说, 数 据 就 包 含 在 指 令 当 中, 取 出 指 令 也 就 取 出 了 可 以 立 即 使 用 的 操 作 数 ( 立 即 数 ) 立 即 寻 址 指 令 举 例 如 下 : SUBS R0,R0,#1 ;R0 1 -> R0 MOV R0,#0xff00 ;0xff00 -> R0 立 即 数 要 以 # 为 前 缀, 表 示 16 进 制 数 值 时 以 0x 表 示 寄 存 器 偏 移 寻 址 寄 存 器 偏 移 寻 址 是 ARM 指 令 集 特 有 的 寻 址 方 式, 当 第 2 操 作 数 是 寄 存 器 偏 移 方 式 时, 第 2 个 寄 存 器 操 作 数 在 与 第 1 个 操 作 数 结 合 之 前, 选 择 进 行 移 位 操 作 寄 存 器 偏 移 寻 址 方 式 指 令 举 例 如 下 : MOV R0,R2,LSL #3 ;R2 的 值 左 移 3 位, 结 果 放 入 R0, 即 R0 = R2 * 8 ANDS R1,R1,R2,LSL R3 ;R2 的 值 左 移 R3 位, 然 后 和 R1 相 与 操 作, 结 果 放 入 R1 可 采 用 的 移 位 操 作 如 下 : LSL: 逻 辑 左 移 (Logical Shift Left), 寄 存 器 中 字 的 低 端 空 出 的 位 补 0 第 2 页
LSR: 逻 辑 右 移 (Logical Shift Right), 寄 存 器 中 字 的 高 端 空 出 的 位 补 0 ASR: 算 术 右 移 (Arithmetic Shift Right), 移 位 过 程 中 保 持 符 号 位 不 变, 即 如 果 源 操 作 数 为 正 数, 则 字 的 高 端 空 出 的 位 补 0, 否 则 补 1 ROR: 循 环 右 移 (Rotate Right), 由 字 的 低 端 移 出 的 位 填 入 字 的 高 端 空 出 的 位 RRX: 带 扩 展 的 循 环 右 移 (Rotate Right extended by 1place), 操 作 数 右 移 一 位, 高 端 空 出 的 位 用 原 C 标 志 值 填 充 各 移 位 操 作 如 下 图 所 示 0 LSL 移 位 操 作 0 LSR 移 位 操 作 ASR 移 位 操 作 ROR 移 位 操 作 C RRX 移 位 操 作 寄 存 器 间 接 寻 址 寄 存 器 间 接 寻 址 指 令 中 的 地 址 码 给 出 的 是 一 个 通 用 寄 存 器 编 号, 所 需 要 的 操 作 数 保 存 在 寄 存 器 指 定 地 址 的 存 储 单 元 中, 即 寄 存 器 为 操 作 数 的 地 址 指 针 寄 存 器 间 接 寻 址 指 令 举 例 如 下 : LDR R1,[R2] ; 将 R2 中 的 数 值 作 为 地 址, 取 出 此 地 址 中 的 数 据 保 存 在 R1 中 SWP R1,R1,[R2]; 将 如 中 的 数 值 作 为 地 址, 取 出 此 地 址 中 的 数 值 与 R1 中 的 值 交 换 基 址 寻 址 基 址 寻 址 是 将 基 址 寄 存 器 的 内 容 与 指 令 中 给 出 的 偏 移 量 相 加, 形 成 操 作 数 的 有 效 地 第 3 页
址, 基 址 寻 址 用 于 访 问 基 址 附 近 的 存 储 单 元, 常 用 于 查 表, 数 组 操 作, 功 能 部 件 寄 存 器 访 问 等 基 址 寻 址 指 令 举 例 如 下 : LDR STR R2,[R3,#0x0F] ; 将 R3 中 的 数 值 加 0x0F 作 为 地 址, 取 出 此 地 址 的 数 值 保 存 在 R2 中 R1,[R0,#-2] ; 将 R0 中 的 数 值 减 2 作 为 地 址, 把 R1 中 的 内 容 保 存 到 此 地 址 位 置 多 寄 存 器 寻 址 多 寄 存 器 寻 址 就 是 一 次 可 以 传 送 几 个 寄 存 器 值, 允 许 一 条 指 令 传 送 16 个 寄 存 器 的 任 何 子 集 或 所 有 寄 存 器 多 寄 存 器 寻 址 指 令 举 例 如 下 : LDMIA R1!,{R2-R7,R12} ; 将 R1 单 元 中 的 数 据 读 出 到 R2-R7,R12,R1 自 动 加 1 STMIA R0!,{R3-R6,R10}; 将 R3-R6,R10 中 的 数 据 保 存 到 R0 指 向 的 地 址,R0 自 动 加 1 使 用 多 寄 存 器 寻 址 指 令 时, 寄 存 器 子 集 的 顺 序 时 由 小 到 大 的 顺 序 排 列, 连 续 的 寄 存 器 可 用 - 连 接, 否 则, 用, 分 隔 书 写 堆 栈 寻 址 堆 栈 是 特 定 顺 序 进 行 存 取 的 存 储 区, 操 作 顺 序 分 为 后 进 先 出 和 先 进 后 出, 堆 栈 寻 址 时 隐 含 的, 它 使 用 一 个 专 门 的 寄 存 器 ( 堆 栈 指 针 ) 指 向 一 块 存 储 区 域 ( 堆 栈 ), 指 针 所 指 向 的 存 储 单 元 就 是 堆 栈 的 栈 顶 存 储 器 堆 栈 可 分 为 两 种 : 向 上 生 长 : 向 高 地 址 方 向 生 长, 称 为 递 增 堆 栈 向 下 生 长 : 向 低 地 址 方 向 生 长, 称 为 递 减 堆 栈 堆 栈 指 针 指 向 最 后 压 入 的 堆 栈 的 有 效 数 据 项, 称 为 满 堆 栈 ; 堆 栈 指 针 指 向 下 一 个 要 放 入 的 空 位 置, 称 为 空 堆 栈 这 样 就 有 4 中 类 型 的 堆 栈 表 示 递 增 和 递 减 的 满 堆 栈 和 空 堆 栈 的 各 种 组 合 满 递 增 : 堆 栈 通 过 增 大 存 储 器 的 地 址 向 上 增 长, 堆 栈 指 针 指 向 内 含 有 效 数 据 项 的 最 高 地 址 指 令 如 LDMFA,STMFA 等 空 递 增 : 堆 栈 通 过 增 大 存 储 器 的 地 址 向 上 增 长, 堆 栈 指 针 指 向 堆 栈 上 的 第 一 个 空 位 置 指 令 如 LDMEA,STMEA 等 第 4 页
满 递 减 : 堆 栈 通 过 减 小 存 储 器 的 地 址 向 下 增 长, 堆 栈 指 针 指 向 内 含 有 效 数 据 项 的 最 低 地 址 指 令 如 LDMFD,STMFD 等 空 递 减 : 堆 栈 通 过 减 小 存 储 器 的 地 址 向 下 增 长, 堆 栈 指 针 指 向 堆 栈 下 的 第 一 个 空 位 置 指 令 如 LDMED,STMED 等 堆 栈 寻 址 指 令 举 例 如 下 : STMFD SP!,{R1-R7,LR} ; 将 R1~R7,LR 入 栈 满 递 减 堆 栈 LDMFD SP!,{R1-R7,LR} ; 数 据 出 栈, 放 入 R1~R7,LR 寄 存 器 满 递 减 堆 栈 块 拷 贝 寻 址 多 寄 存 器 传 送 指 令 用 于 一 块 数 据 从 存 储 器 的 某 一 位 置 拷 贝 到 另 一 位 置 块 拷 贝 寻 址 指 令 举 例 如 下 : STMIA R0!,{R1-R7} ; 将 R1~R7 的 数 据 保 存 到 存 储 器 中, 存 储 器 指 针 在 保 存 第 一 ; 个 值 之 后 增 加, 增 长 方 向 为 向 上 增 长 STMIB R0!,{R1-R7} ; 将 R1~R7 的 数 据 保 存 到 存 储 器 中, 存 储 器 指 针 在 保 存 第 一 ; 个 值 之 前 增 加, 增 长 方 向 为 向 上 增 长 STMDA R0!,{R1-R7} ; 将 R1~R7 的 数 据 保 存 到 存 储 器 中, 存 储 器 指 针 在 保 存 第 一 ; 个 值 之 后 增 加, 增 长 方 向 为 向 下 增 长 STMDB R0!,{R1-R7} ; 将 R1~R7 的 数 据 保 存 到 存 储 器 中, 存 储 器 指 针 在 保 存 第 一 ; 个 值 之 前 增 加, 增 长 方 向 为 向 下 增 长 相 对 寻 址 相 对 寻 址 是 基 址 寻 址 的 一 种 变 通, 由 程 序 计 数 器 PC 提 供 基 准 地 址, 指 令 中 的 地 址 码 字 段 作 为 偏 移 量, 两 者 相 加 后 得 到 的 地 址 即 为 操 作 数 的 有 效 地 址 相 对 寻 址 指 令 举 例 如 下 : BL ROUTE1 ; 调 用 到 ROUTE1 子 程 序 BEQ LOOP ; 条 件 跳 转 到 LOOP 标 号 处 LOOP MOV R2,#2 第 5 页
ROUTE1 第 6 页
指 令 集 介 绍 ARM 指 令 集 指 令 格 式 基 本 格 式 <opcode>{<cond>}{s} <Rd>,<Rn>{,<opcode2>} 其 中,<> 内 的 项 是 必 须 的,{} 内 的 项 是 可 选 的, 如 <opcode> 是 指 令 助 记 符, 是 必 须 的, 而 {<cond>} 为 指 令 执 行 条 件, 是 可 选 的, 如 果 不 写 则 使 用 默 认 条 件 AL( 无 条 件 执 行 ) opcode cond S Rd Rn operand2 指 令 助 记 符, 如 LDR,STR 等 执 行 条 件, 如 EQ,NE 等 是 否 影 响 CPSR 寄 存 器 的 值, 书 写 时 影 响 CPSR, 否 则 不 影 响 目 标 寄 存 器 第 一 个 操 作 数 的 寄 存 器 第 二 个 操 作 数 指 令 格 式 举 例 如 下 : LDR R0,[R1] ; 读 取 R1 地 址 上 的 存 储 器 单 元 内 容, 执 行 条 件 AL BEQ ADDS DATAEVEN ; 跳 转 指 令, 执 行 条 件 EQ, 即 相 等 跳 转 到 DATAEVEN R1,R1,#1 ; 加 法 指 令,R1+1=R1 影 响 CPSR 寄 存 器, 带 有 S SUBNES R1,R1,#0xD; 条 件 执 行 减 法 运 算 (NE),R1-0xD=>R1, 影 响 CPSR 寄 存 器, 带 有 S 第 2 个 操 作 数 下 : 在 ARM 指 令 中, 灵 活 的 使 用 第 2 个 操 作 数 能 提 高 代 码 效 率, 第 2 个 操 作 数 的 形 式 如 #immed_8r 常 数 表 达 式, 该 常 数 必 须 对 应 8 位 位 图, 即 常 数 是 由 一 个 8 位 的 常 数 循 环 移 位 偶 数 第 7 页
位 得 到 合 法 常 量 : 0x3FC 0 0xF0000000 200,0xF0000001 非 法 常 量 : 0x1FE 511 0xFFFF 0x1010 0xF0000010 常 数 表 达 式 应 用 举 例 如 下 : MOV R0,#1 ;R0=1 AND LDR R1,R2,#0x0F ;R2 与 0x0F, 结 果 保 存 在 R1 R0,[R1],#-4 ; 读 取 R1 地 址 上 的 存 储 器 单 元 内 容, 且 R1=R1-4 Rm 寄 存 器 方 式, 在 寄 存 器 方 式 下 操 作 数 即 为 寄 存 器 的 数 值 寄 存 器 方 式 应 用 举 例 : SUB R1,R1,R2 MOV PC,R0 LDR R0,[R1],-R2 ;R1-R2=>R1 ;PC=R0, 程 序 跳 转 到 指 定 地 址 ; 读 取 R1 地 址 上 的 存 储 器 单 元 内 容 并 存 入 R0, 且 R1=R1-R2 Rm,shift 如 下 : 寄 存 器 移 位 方 式 将 寄 存 器 的 移 位 结 果 作 为 操 作 数, 但 RM 值 保 存 不 变, 移 位 方 法 ASR #n LSL #n LSR #n ROR #n RRX 算 术 右 移 n 位 (1 n 32) 逻 辑 左 移 n 位 (1 n 31) 逻 辑 左 移 n 位 (1 n 32) 循 环 右 移 n 位 (1 n 31) 带 扩 展 的 循 环 右 移 1 位 type Rs 其 中,type 为 ASR,LSL, 和 ROR 中 的 一 种 ;Rs 偏 移 量 寄 存 器, 低 8 位 有 效, 若 其 值 大 于 或 等 于 32, 则 第 2 个 操 作 数 的 结 果 为 0(ASR ROR 例 外 ) 寄 存 器 偏 移 方 式 应 用 举 例 : ADD R1,R1,R1,LSL #3 ;R1=R1*9 第 8 页
SUB R1,R1,R2,LSR#2 ;R1=R1-R2*4 R15 为 处 理 器 的 程 序 计 数 器 PC, 一 般 不 要 对 其 进 行 操 作, 而 且 有 些 指 令 是 不 允 许 使 用 R15, 如 UMULL 指 令 条 件 码 使 用 指 令 条 件 码, 可 实 现 高 效 的 逻 辑 操 作, 提 高 代 码 效 率 条 件 码 表 条 件 码 助 记 符 标 志 含 义 EQ Z=1 相 等 NE Z=0 不 相 等 CS/HS C=1 无 符 号 数 大 于 或 等 于 CC/LO C=0 无 符 号 数 小 于 MI N=1 负 数 PL N=0 正 数 或 零 VS V=1 溢 出 VC V=0 没 有 溢 出 HI C=1,Z=0 无 符 号 数 大 于 LS C=0,Z=1 无 符 号 数 小 于 或 等 于 GE N=V 带 符 号 数 大 于 或 等 于 LT N!=V 带 符 号 数 小 于 GT Z=0,N=V 带 符 号 数 大 于 LE Z=1,N!=V 带 符 号 数 小 于 或 等 于 AL 任 何 无 条 件 执 行 ( 指 令 默 认 条 件 ) 对 于 Thumb 指 令 集, 只 有 B 指 令 具 有 条 件 码 执 行 功 能, 此 指 令 条 件 码 同 表 2.1, 但 如 果 为 无 条 件 执 行 时, 条 件 码 助 记 符 AL 不 能 在 指 令 中 书 写 条 件 码 应 用 举 例 如 下 : 比 较 两 个 值 大 小, 并 进 行 相 应 加 1 处 理,C 代 码 为 if(a>b)a++; else b++; 对 应 的 ARM 指 令 如 下 其 R0 为 a,r1 为 b CMP R0,R1 ;R0 与 R1 比 较 ADDHI R0,R0,#1 ADDLS R1,R1,#1 ; 若 R0>R1, 则 R0=R0+1 ; 若 R0<=R1, 则 R1=R1+1 若 两 个 条 件 均 成 立, 则 将 这 两 个 数 值 相 加,C 代 码 为 第 9 页
If((a!=10)&&(b!=20)) a=a+b; 对 应 的 ARM 指 令 如 下. 其 中 R0 为 a,r1 为 b. CMP R0,#10 ; 比 较 R0 是 否 为 10 CMPNE R1,#20 ; 若 R0 不 为 10, 则 比 较 R1 是 否 20 ADDNE R0,R0,R1 ; 若 R0 不 为 10 且 R1 不 为 20, 指 令 执 行,R0=R0+R1 第 10 页
ARM 存 储 器 访 问 指 令 ARM 处 理 是 加 载 / 存 储 体 系 结 构 的 典 型 的 RISC 处 理 器, 对 存 储 器 的 访 问 只 能 使 用 加 载 和 存 储 指 令 实 现 ARM 的 加 载 / 存 储 指 令 是 可 以 实 现 字 半 字, 无 符 / 有 符 字 节 操 作 ; 批 量 加 载 / 存 储 指 令 可 实 现 一 条 指 令 加 载 / 存 储 多 个 寄 存 器 的 内 容, 大 大 提 高 效 率 ;SWP 指 令 是 一 条 寄 存 器 和 存 储 器 内 容 交 换 的 指 令, 可 用 于 信 号 量 操 作 等 ARM 处 理 器 是 冯. 诺 依 曼 存 储 结 构, 程 序 空 间 RAM 空 间 及 IO 映 射 空 间 统 一 编 址, 除 对 对 RAM 操 作 以 外, 对 外 围 IO 程 序 数 据 的 访 问 均 要 通 过 加 载 / 存 储 指 令 进 行 ARM 存 储 访 问 指 令 表 助 记 符 说 明 操 作 条 件 码 位 置 LDR Rd,addressing 加 载 字 数 据 Rd [addressing],addressing 索 引 LDR{cond} LDRB Rd,addressing 加 载 无 符 字 节 数 据 Rd [addressing],addressing 索 引 LDR{cond}B LDRT Rd,addressing 以 用 户 模 式 加 载 字 数 据 Rd [addressing],addressing 索 引 LDR{cond}T LDRBT Rd,addressing 以 用 户 模 式 加 载 无 符 号 字 数 据 Rd [addressing],addressing 索 引 LDR{cond}BT LDRH Rd,addressing 加 载 无 符 半 字 数 据 Rd [addressing],addressing 索 引 LDR{cond}H LDRSB Rd,addressing 加 载 有 符 字 节 数 据 Rd [addressing],addressing 索 引 LDR{cond}SB LDRSH Rd,addressing 加 载 有 符 半 字 数 据 Rd [addressing],addressing 索 引 LDR{cond}SH STR Rd,addressing 存 储 字 数 据 [addressing] Rd,addressing 索 引 STR{cond} STRB Rd,addressing 存 储 字 节 数 据 [addressing] Rd,addressing 索 引 STR{cond}B STRT Rd,addressing 以 用 户 模 式 存 储 字 数 据 [addressing] Rd,addressing 索 引 STR{cond}T SRTBT Rd,addressing 以 用 户 模 式 存 储 字 节 数 据 [addressing] Rd,addressing 索 引 STR{cond}BT STRH Rd,addressing 存 储 半 字 数 据 [addressing] Rd,addressing 索 引 STR{cond}H LDM{mode} Rn{!},reglist 批 量 ( 寄 存 器 ) 加 载 reglist [Rn],Rn 回 存 等 LDM{cond}{more} STM{mode} Rn{!},rtglist 批 量 ( 寄 存 器 ) 存 储 [Rn] reglist,rn 回 存 等 STM{cond}{more} SWP Rd,Rm,Rn 寄 存 器 和 存 储 器 字 数 据 交 换 Rd [Rd],[Rn] [Rm](Rn Rd 或 Rm) SWP{cond} SWPB Rd,Rm,Rn 寄 存 器 和 存 储 器 字 节 数 据 交 换 Rd [Rd],[Rn] [Rm](Rn Rd 或 Rm) SWP{cond}B LDR 和 STR 加 载 / 存 储 字 和 无 符 号 字 节 指 令. 使 用 单 一 数 据 传 送 指 令 (STR 和 LDR) 来 装 载 和 存 储 单 一 字 节 或 字 的 数 据 从 / 到 内 存.LDR 指 令 用 于 从 内 存 中 读 取 数 据 放 入 寄 存 器 中 ;STR 指 令 用 于 将 寄 存 器 中 的 数 据 保 存 到 内 存. 指 令 格 式 如 下 : LDR{cond}{T} STR{cond}{T} Rd,< 地 址 >; 加 载 指 定 地 址 上 的 数 据 ( 字 ), 放 入 Rd 中 Rd,< 地 址 >; 存 储 数 据 ( 字 ) 到 指 定 地 址 的 存 储 单 元, 要 存 储 的 数 据 在 Rd 中 LDR{cond}B{T} Rd,< 地 址 >; 加 载 字 节 数 据, 放 入 Rd 中, 即 Rd 最 低 字 节 有 效, 高 24 位 清 零 第 11 页
STR{cond}B{T} Rd,< 地 址 >; 存 储 字 节 数 据, 要 存 储 的 数 据 在 Rd, 最 低 字 节 有 效 其 中,T 为 可 选 后 缀, 若 指 令 有 T, 那 么 即 使 处 理 器 是 在 特 权 模 式 下, 存 储 系 统 也 将 访 问 看 成 是 处 理 器 是 在 用 户 模 式 下.T 在 用 户 模 式 下 无 效, 不 能 与 前 索 引 偏 移 一 起 使 用 T. LDR/STR 指 令 寻 址 是 非 常 灵 活 的, 由 两 部 分 组 成, 一 部 分 为 一 个 基 址 寄 存 器, 可 以 为 任 一 个 通 用 寄 存 器, 另 一 部 分 为 一 个 地 址 偏 移 量. 地 址 偏 移 量 有 以 下 3 种 格 式 : (1) 立 即 数. 立 即 数 可 以 是 一 个 无 符 号 数 值, 这 个 数 据 可 以 加 到 基 址 寄 存 器, 也 可 以 从 基 址 寄 存 器 中 减 去 这 个 数 值. 指 令 举 例 如 下 : LDR R1,[R0,#0x12] ; 将 R0+0x12 地 址 处 的 数 据 读 出, 保 存 到 R1 中 (R0 的 值 不 变 ) LDR R1,[R0,#-0x12]; 将 R0-0x12 地 址 处 的 数 据 读 出, 保 存 到 R1 中 (R0 的 值 不 变 ) LDR R1,[R0] ; 将 R0 地 址 处 的 数 据 读 出, 保 存 到 R1 中 ( 零 偏 移 ) (2) 寄 存 器. 寄 存 器 中 的 数 值 可 以 加 到 基 址 寄 存 器, 也 可 以 从 基 址 寄 存 器 中 减 去 这 个 数 值. 指 令 举 例 值. 指 令 举 例 如 下 : LDR R1,[R0,R2] ; 将 R0+R2 地 址 的 数 据 计 读 出, 保 存 到 R1 中 (R0 的 值 不 变 ) LDR R1,[R0,-R2] ; 将 R0-R2 地 址 处 的 数 据 计 读 出, 保 存 到 R1 中 (R0 的 值 不 变 ) (3) 寄 存 器 及 移 位 常 数. 寄 存 器 移 位 后 的 值 可 以 加 到 基 址 寄 存 器, 也 可 以 从 基 址 寄 存 器 中 减 去 这 个 数 值. 指 令 举 例 如 下 : LDR R1,[R0,R2,LSL #2] ; 将 R0+R2*4 地 址 处 的 数 据 读 出, 保 存 到 R1 中 (R0,R2 的 值 不 变 ) LDR R1,[R0,-R2,LSL #2]; 将 R0-R2*4 地 址 处 的 数 据 计 读 出, 保 存 到 R1 中 (R0,R2 的 值 不 变 ) 从 寻 址 方 式 的 地 址 计 算 方 法 分, 加 载 / 存 储 指 令 有 以 下 4 种 形 式 : (1) 零 偏 移.Rn 的 值 作 为 传 送 数 据 的 地 址, 即 地 址 偏 移 量 为 0. 指 令 举 例 如 下 : LDR Rd,[Rn] (2) 前 索 引 偏 移. 在 数 据 传 送 之 前, 将 偏 移 量 加 到 Rn 中, 其 结 果 作 为 传 送 数 据 的 存 储 地 址. 若 使 用 后 缀!, 则 结 果 写 回 到 Rn 中, 且 Rn 值 不 允 许 为 R15. 指 令 举 例 如 下 : LDR LDR Rd,[Rn,#0x04]! Rd,[Rn,#-0x04] (3) 程 序 相 对 偏 移. 程 序 相 对 偏 移 是 索 引 形 式 的 另 一 个 版 本. 汇 编 器 由 PC 寄 存 器 计 算 偏 移 量, 并 将 PC 寄 存 器 作 为 Rn 生 成 前 索 引 指 令. 不 能 使 用 后 缀!. 指 令 举 例 如 下 : LDR Rd,label ;label 为 程 序 标 号,label 必 须 是 在 当 前 指 令 的 ±4KB 范 围 内 (4) 后 索 引 偏 移.Rn 的 值 用 做 传 送 数 据 的 存 储 地 址. 在 数 据 传 送 后, 将 偏 移 量 与 Rn 第 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 STR{cond}H Rd,< 地 址 > ; 加 载 半 字 数 据, 放 入 Rd 中, 即 Rd 最 低 16 位 有 效, 高 16 位 清 零 Rd,< 地 址 > ; 存 储 半 字 数 据, 要 存 储 的 数 据 在 Rd, 最 低 16 位 有 效 说 明 : 带 符 号 位 半 字 / 字 节 加 载 是 指 带 符 号 位 加 载 扩 展 到 32 位 ; 无 符 号 位 半 字 加 载 是 指 零 扩 展 到 32 位. 地 址 对 准 -- 对 半 字 传 送 的 地 址 必 须 为 偶 数. 非 半 字 对 准 的 半 字 加 载 将 使 Rd 内 容 不 可 靠, 非 半 字 对 准 的 半 字 存 储 将 使 指 定 地 址 的 2 字 节 存 储 内 容 不 可 靠. 加 载 / 存 储 半 字 和 带 符 号 字 节 指 令 举 例 如 下 : LDRSB R1[R0,R3] ; 将 R0+R3 地 址 上 的 字 节 数 据 读 出 到 R1, 高 24 位 用 符 号 位 扩 展 LDRSH R1,[R9] ; 将 R9 地 址 上 的 半 字 数 据 读 出 到 R1, 高 16 位 用 符 号 位 扩 展 LDRH SHRH R6,[R2],#2 ; 将 R2 地 址 上 的 半 字 数 据 读 出 到 R6, 高 16 位 用 零 扩 展,,R2=R2+1 R1,[R0,#2]!; 将 R1 的 数 据 保 存 到 R2+2 地 址 中, 只 存 储 低 2 字 节 数 据,R0=R0+2 LDR/STR 指 令 用 于 对 内 存 变 量 的 访 问, 内 存 缓 冲 区 数 据 的 访 问 查 表 外 围 部 件 的 控 制 操 作 等 等, 若 使 用 LDR 指 令 加 载 数 据 到 PC 寄 存 器, 则 实 现 程 序 跳 转 功 能, 这 样 也 就 实 现 了 程 序 散 转 变 量 的 访 问 NumCount EQU 0x40003000 ; 定 义 变 量 NumCount 第 13 页
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 LDR R0,=GPIO-BASE 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 DCD FUN-SUB1 FUN-SUB2 LDM 和 STM 批 量 加 载 / 存 储 指 令 可 以 实 现 在 一 组 寄 存 器 和 一 块 连 续 的 内 存 单 元 之 间 传 输 数 据.LDM 为 加 载 多 个 寄 存 器,STM 为 存 储 多 个 寄 存 器. 允 许 一 条 指 令 传 送 16 个 寄 存 器 的 任 何 子 集 或 所 有 寄 存 器. 指 令 格 式 如 下 : 第 14 页
LDM{cond}< 模 式 > STM{cond}< 模 式 > Rn{!},reglist{^} 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 LDMFD SP!,{R0-R7,LR} ; 现 场 保 存, 将 R0~R7 LR 入 栈 SP!,{R0-R7,PC}^; 恢 复 现 场, 异 常 处 理 返 回 在 进 行 数 据 复 制 时, 先 设 置 好 源 数 据 指 针, 然 后 使 用 块 拷 贝 寻 址 指 令 LDMIA/STMIA LDMIB/STMIB LDMDA/STMDA LDMDB/STMDB 进 行 读 取 和 存 储 而 进 行 堆 栈 操 作 时, 则 要 先 设 置 堆 栈 指 针, 一 般 使 用 SP 然 后 使 用 堆 栈 寻 址 指 令 STMFD/LDMFD STMED LDMED STMFA/LDMFA STMEA/LDMEA 实 现 堆 栈 操 作 第 15 页
多 寄 存 器 传 送 指 令 示 意 图 如 图 所 示, 其 中 R1 为 指 令 执 行 前 的 基 址 寄 存 器,R1 则 为 指 令 执 行 完 后 的 基 址 寄 存 器. R1 R1 R7 R6 R5 4008H 4004H 4000H a) 指 令 STMIA R1!,{R5-R7} R1 R1 R7 R6 R5 4008H 4004H 4000H b) 指 令 STMIB R1!,{R5-R7} R1 R1 R7 R6 R5 4008H 4004H 4000H c) 指 令 STMDA R1!, {R5-R7} R1 R1 R7 R6 R5 4008H 4004H 4000H d) 指 令 STMDB R1!,{R5-R7} 数 据 是 存 储 在 基 址 寄 存 器 的 地 址 之 上 还 是 之 下, 地 址 是 在 存 储 第 一 个 值 之 前 还 是 之 后 增 加 还 是 减 少. 第 16 页
增 加 增 加 之 前 之 后 之 前 之 后 多 寄 存 器 传 送 指 令 映 射 向 上 生 长 向 下 生 长 满 空 满 空 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] 第 17 页
其 中,B 为 可 选 后 缀, 若 有 B, 则 交 换 字 节, 否 则 交 换 32 位 字 :Rd 为 数 据 从 存 储 器 加 载 到 的 寄 存 器 ;Rm 的 数 据 用 于 存 储 到 存 储 器 中, 若 Rm 与 Rn 相 同, 则 为 寄 存 器 与 存 储 器 内 容 进 行 交 换 ;Rn 为 要 进 行 数 据 交 换 的 存 储 器 地 址,Rn 不 能 与 Rd 和 Rm 相 同. SWP 指 令 举 例 如 下 : SWP R1,R1,[R0] ; 将 R1 的 内 容 与 R0 指 向 的 存 储 单 元 的 内 容 进 行 交 换 SWP R1,R2,,[R0] ; 将 R0 指 向 的 存 储 单 元 内 容 读 取 一 字 节 数 据 到 R1 中 ( 高 24 位 清 零 ), 并 将 R2 的 内 容 写 入 到 该 内 存 单 元 中 ( 最 低 字 节 有 效 ) 使 用 SWP 指 令 可 以 方 便 地 进 行 信 号 量 的 操 作 : 12C_SEM EQU 0x40003000 12C_SEM_WAIT MOV LDR R0,#0 R0,=12C_SEM SWP R1,R1,[R0] ; 取 出 信 号 量, 并 设 置 其 为 0 CMP R1,#0 ; 判 断 是 否 有 信 号 BEQ 12C_SEM_WAIT ; 若 没 有 信 号, 则 等 待 第 18 页
ARM 数 据 处 理 指 令 数 据 处 理 指 令 大 致 可 分 为 3 类 ; 数 据 传 送 指 令 ( 如 MOV MVN), 算 术 逻 辑 运 算 指 令 ( 如 ADD,SUM,AND), 比 较 指 令 ( 如 CMP,TST). 数 据 处 理 指 令 只 能 对 寄 存 器 的 内 容 进 行 操 作. 所 有 ARM 数 据 处 理 指 令 均 可 选 择 使 用 S 后 缀, 以 影 响 状 态 标 志. 比 较 指 令 CMP,CMN,TST 和 TEQ 不 需 要 后 缀 S, 它 们 会 直 接 影 响 状 态 标 志. ARM 数 据 处 理 指 令 助 记 符 号 说 明 操 作 条 件 码 位 置 MOV Rd,operand2 数 据 转 送 Rd operand2 MOV {cond}{s} MVN Rd,operand2 数 据 非 转 送 Rd (operand2) MVN {cond}{s} ADD Rd,Rn operand2 加 法 运 算 指 令 Rd Rn+operand2 ADD {cond}{s} SUB Rd,Rn operand2 减 法 运 算 指 令 Rd Rn-operand2 SUB {cond}{s} RSB Rd,Rn operand2 逆 向 减 法 指 令 Rd operand2-rn RSB {cond}{s} ADC Rd,Rn operand2 带 进 位 加 法 Rd Rn+operand2+carry ADC {cond}{s} SBC Rd,Rn operand2 带 进 位 减 法 指 令 Rd Rn-operand2-(NOT)Carry SBC {cond}{s} RSC Rd,Rn operand2 带 进 位 逆 向 减 法 指 令 Rd operand2-rn-(not)carry RSC {cond}{s} AND Rd,Rn operand2 逻 辑 与 操 作 指 令 Rd Rn&operand2 AND {cond}{s} ORR Rd,Rn operand2 逻 辑 或 操 作 指 令 Rd Rn operand2 ORR {cond}{s} EOR Rd,Rn operand2 逻 辑 异 或 操 作 指 令 Rd Rn^operand2 EOR {cond}{s} BIC Rd,Rn operand2 位 清 除 指 令 Rd Rn&(~operand2) BIC {cond}{s} CMP Rn,operand2 比 较 指 令 标 志 N Z C V Rn-operand2 CMP {cond} CMN Rn,operand2 负 数 比 较 指 令 标 志 N Z C V Rn+operand2 CMN {cond} TST Rn,operand2 位 测 试 指 令 标 志 N Z C V Rn&operand2 TST {cond} TEQ Rn,operand2 相 等 测 试 指 令 标 志 N Z C V Rn^operand2 TEQ {cond} 第 19 页
数 据 传 送 指 令 MOV 数 据 传 送 指 令. 将 8 位 图 立 即 数 或 寄 存 器 (operant2) 传 送 到 目 标 寄 存 器 Rd, 可 用 于 移 位 运 算 等 操 作. 指 令 格 式 如 下 : MOV{cond}{S} Rd,operand2 MOV 指 令 举 例 如 下 : MOV R1#0x10 ;R1=0x10 MOV R0,R1 ;R0=R1 MOVS R3,R1,LSL #2 ;R3=R1<<2, 并 影 响 标 志 位 MOV PC,LR ;PC=LR, 子 程 序 返 回 MVN 数 据 非 传 送 指 令. 将 8 位 图 立 即 数 或 寄 存 器 (operand2) 按 位 取 反 后 传 送 到 目 标 寄 存 器 (Rd), 因 为 其 具 有 取 反 功 能, 所 以 可 以 装 载 范 围 更 广 的 立 即 数. 指 令 格 式 如 下 : MVN{cond}{S} Rd,operand2 MVN 指 令 举 例 如 下 : MVN R1,#0xFF ;R1=0xFFFFFF00 MVN R1,R2 ; 将 R2 取 反, 结 果 存 到 R1 算 术 逻 辑 运 算 指 令 ADD 下 : 加 法 运 算 指 令. 将 operand2 数 据 与 Rn 的 值 相 加, 结 果 保 存 到 Rd 寄 存 器. 指 令 格 式 如 ADD{cond}{S} Rd,Rn,operand2 ADD 指 令 举 例 如 下 : ADDS R1,R1,#1 ;R1=R1+1 ADD R1,R1,R2 ;R1=R1+R2 ADDS R3,R1,R2,LSL #2 ;R3=R1+R2<<2 第 20 页
SUB 减 法 运 算 指 令. 用 寄 存 器 Rn 减 去 operand2. 结 果 保 存 到 Rd 中. 指 令 格 式 如 下 : SUB{cond}{S} Rd,Rn,operand2 SUB 指 令 举 例 如 下 SUBS R0,R0,#1 ;R0=R0-1 SUBS R2,R1,R2 ;R2=R1-R2 SUB R6,R7,#0x10 ;R6=R7-0x10 RSB 逆 向 减 法 指 令. 用 寄 存 器 operand2 减 法 Rn, 结 果 保 存 到 Rd 中. 指 令 格 式 如 下 : RSB{cond}{S} Rd,Rn,operand2 SUB 指 令 举 例 如 下 RSB R3,R1,#0xFF00 ;R3=0xFF00-R1 RSBS R1,R2,R2,LSL #2 ;R1=R2<<2-R2=R2 3 RSB R0,R1,#0 ;R0=-R1 ADC 带 进 位 加 法 指 令. 将 operand2 的 数 据 与 Rn 的 值 相 加, 再 加 上 CPSR 中 的 C 条 件 标 志 位. 结 果 保 存 到 Rd 寄 存 器. 指 令 格 式 如 下 ; ADC{cond}{S} Rd,Rn,operand2 ADC 指 令 举 例 如 下 : ADDS R0,R0,R2 ADC R1,R1,R3 ; 使 用 ADC 实 现 64 位 加 法,(R1 R0)=(R1 R0)+(R3 R2) SBC 带 进 位 减 法 指 令 用 寄 存 器 Rn 减 去 operand2, 再 减 去 CPSR 中 的 C 条 件 标 志 位 的 非 ( 即 若 C 标 志 清 零, 则 结 果 减 去 1), 结 果 保 存 到 Rd 中 指 令 格 式 如 下 : SCB{cond}{S}Rd,Rn,operand2 SBC 指 令 举 例 如 下 SUBS R0,R0,R2 SBC R1,R1,R3 ; 使 用 SBC 实 现 64 位 减 法,(R1,R0)-(R3,R2) 第 21 页
RSC 带 进 位 逆 向 减 法 指 令. 用 寄 存 器 operand2 减 去 Rn, 再 减 去 CPSR 中 的 C 条 件 标 志 位, 结 果 保 存 到 Rd 中. 指 令 格 式 如 下 : RSC{cond}{S} Rd,Rn,operand2 RSC 指 令 举 例 如 下 : RSBS R2,R0,#0 RSC R3,R1,#0 ; 使 用 RSC 指 令 实 现 求 64 位 数 值 的 负 数 AND 逻 辑 与 操 作 指 令. 将 operand2 值 与 寄 存 器 Rn 的 值 按 位 作 逻 辑 与 操 作, 结 果 保 存 到 Rd 中. 指 令 格 式 如 下 : AND{cond}{S} Rd,Rn,operand2 AND 指 令 举 例 如 下 : ANDS R0,R0,#x01 ;R0=R0&0x01, 取 出 最 低 位 数 据 AND R2,R1,R3 ;R2=R1&R3 ORR 逻 辑 或 操 作 指 令. 将 operand2 的 值 与 寄 存 器 Rn 的 值 按 位 作 逻 辑 或 操 作, 结 果 保 存 到 Rd 中. 指 令 格 式 如 下 : ORR{cond}{S} Rd,Rn,operand2 ORR 指 令 举 例 如 下 : ORR R0,R0,#x0F ; 将 R0 的 低 4 位 置 1 MOV R1,R2,LSR #4 ORR R3,R1,R3,LSL #8 ; 使 用 ORR 指 令 将 近 R2 的 高 8 位 数 据 移 入 到 R3 低 8 位 中 EOR 逻 辑 异 或 操 作 指 令. 将 operand2 的 值 与 寄 存 器 Rn 的 值 按 位 作 逻 辑 异 或 操 作, 结 果 保 存 到 Rd 中. 指 令 格 式 如 下 : EOR{cond}{S}Rd,Rn,operand2 EOR 指 令 举 例 如 下 : 第 22 页
EOR R1,R1,#0x0F ; 将 R1 的 低 4 位 取 反 EOR R2,R1,R0 ;R2=R1^R0 EORS R0,R5,#0x01 ; 将 R5 和 0x01 进 行 逻 辑 异 或, 结 果 保 存 到 R0, 并 影 响 标 志 位 BIC 位 清 除 指 令. 将 寄 存 器 Rn 的 值 与 operand2 的 值 的 反 码 按 位 作 逻 辑 与 操 作, 结 果 保 存 到 Rd 中. 指 令 格 式 如 下 : BIC{cond}{S}Rd,Rn,operand2 BIC 指 令 举 例 如 下 : BIC R1,R1,#0x0F ; 将 R1 的 低 4 位 清 零, 其 它 位 不 变 BIC R1,R2,R3 ; 将 拭 的 反 码 和 R2 相 逻 辑 与, 结 果 保 存 到 R1 比 较 指 令 CMP 比 较 指 令. 指 令 使 用 寄 存 器 Rn 的 值 减 去 operand2 的 值, 根 据 操 作 的 结 果 理 新 CPSR 中 的 相 应 条 件 标 志 位, 以 便 后 面 的 指 令 根 据 相 应 的 条 件 标 志 来 判 断 是 否 执 行. 指 令 格 式 如 下 : CMP{cond} Rn,operand2 CMP 指 令 举 例 如 下 : CMP R1,#10 ;R1 与 10 比 较, 设 置 相 关 标 志 位 CMP R1,R2 ;R1 与 R2 比 较, 设 置 相 关 标 志 位 CMP 指 令 与 SUBS 指 令 的 区 别 在 于 CMP 指 令 不 保 存 运 算 结 果. 在 进 行 两 个 数 据 大 小 判 断 时, 常 用 CMP 指 令 及 相 应 的 条 件 码 来 操 作. CMN 负 数 比 较 指 令. 指 令 使 用 寄 存 器 Rn 与 值 加 上 operand2 的 值, 根 据 操 作 的 结 果 理 新 CPSR 中 的 相 应 条 件 标 志 位, 以 便 后 面 的 指 令 根 据 相 应 的 条 件 标 志 来 判 断 是 否 执 行, 指 令 格 式 如 下 : CMN{cond} Rn,operand2 CMN R0,#1 ;R0+1, 判 断 R0 是 否 为 1 的 补 码, 若 是 Z 置 位 第 23 页
CMN 指 令 与 ADDS 指 令 的 区 别 在 于 CMN 指 令 不 保 存 运 算 结 果.CMN 指 令 可 用 于 负 数 比 较, 比 如 CMNR0,#1 指 令 则 表 示 R0 与 -1 比 较, 若 R0 为 -( 即 1 的 补 码 ), 则 Z 置 位, 否 则 Z 复 位. TST 位 测 试 指 令. 指 令 将 寄 存 器 Rn 的 值 与 operand2 的 值 按 位 作 逻 辑 与 操 作, 根 据 操 作 的 结 果 理 新 CPSR 中 相 应 的 条 件 标 志 位, 以 便 后 面 指 令 根 据 相 应 的 条 件 标 志 来 判 断 是 否 执 行. 指 令 格 式 如 下 : TST{cond} Rn,operand2 TST 指 令 举 例 如 下 : TST R0,#0x01 ; 判 断 R0 的 最 低 位 是 否 为 0 TST R1,#0x0F ; 判 断 R1 的 低 4 位 是 否 为 0 TST 指 令 与 ANDS 指 令 的 区 别 在 于 TST4 指 令 不 保 存 运 算 结 果.TST 指 令 通 常 于 EQ,NE 条 件 码 配 合 使 用, 当 所 有 测 试 位 均 为 0 时,EQ 有 效, 而 只 要 有 一 个 测 试 为 不 为 0, 则 NE 有 效. TEQ 相 等 测 试 指 令. 指 令 寄 存 器 Rn 的 值 与 operand2 的 值 按 位 作 逻 辑 异 或 操 作, 根 据 操 作 的 结 果 理 新 CPSR 中 相 应 条 件 标 志 位, 以 便 后 面 的 指 令 根 据 相 应 的 条 件 标 志 来 判 断 是 否 执 行. 指 令 格 式 如 下 : TEQ{cond} Rn,operand2 TEQ 指 令 举 例 如 下 : TEQ R0,R1 ; 比 较 R0 与 R1 是 否 相 等 ( 不 影 响 V 位 和 C 位 ) TST 指 令 与 EORS 指 令 的 区 别 在 于 TST 指 令 不 保 存 运 算 结 果. 使 用 TEQ 进 行 相 等 测 试, 常 与 EQNE 条 件 码 配 合 使 用, 当 两 个 数 据 相 等 时,EQ 有 效, 否 则 NE 有 效. 第 24 页
乘 法 指 令 ARM7TDMI(-S) 具 有 32 32 乘 法 指 令,32 32 乘 加 指 令,32 32 结 果 为 64 位 的 乘 / 乘 法 指 令. ARM 乘 法 指 令 助 记 符 说 明 操 作 条 件 码 位 置 MUL Rd,Rm,Rs 32 位 乘 法 指 令 Rd Rm*Rs (Rd Rm) MUL{cond}{S} MLA Rd,Rm,Rs,Rn 32 位 乘 加 指 令 Rd Rm*Rs+Rn (Rd Rm) MLA{cond}{S} UMULL RdLo,RdHi,Rm,Rs 64 位 无 符 号 乘 法 指 令 (RdLo,RdHi) Rm*Rs UMULL{cond}{S} UMLAL RdLo,RdHi,Rm,Rs 64 位 无 符 号 乘 加 指 令 (RdLo,RdHi) Rm*Rs+(RdLo,RdHi) UMLAL{cond}{S} SMULL RdLo,RdHi,Rm,Rs 64 位 有 符 号 乘 法 指 令 (RdLo,RdHi) Rm*Rs SMULL{cond}{S} SMLAL RdLo,RdHi,Rm,Rs 64 位 有 符 号 乘 加 指 令 (RdLo,RdHi) Rm*Rs+(RdLo,RdHi) SMLAL{cond}{S} MUL 如 下 : 32 位 乘 法 指 令. 指 令 将 Rm 和 Rs 中 的 值 相 乘, 结 果 的 低 32 位 保 存 到 Rd 中. 指 令 格 式 MUL{cond}{S} Rd,Rm,Rs MUL 指 令 举 例 如 下 : MUL R1,R2,R3 ;R1=R2 R3 MULS R0,R3,R7 ;R0=R3 R7, 同 时 设 置 CPSR 中 的 N 位 和 Z 位 MLA 32 位 乘 加 指 令. 指 令 将 Rm 和 Rs 中 的 值 相 乘, 再 将 乘 积 加 上 第 3 个 操 作 数, 结 果 的 低 32 位 保 存 到 Rd 中. 指 令 格 式 如 下 : MLA{cond}{S} Rd,Rm,Rs,Rn MLA 指 令 举 例 如 下 : MLA R1,R2,R3,R0 ;R1=R2 R3+10 UMULL 64 位 无 符 号 乘 法 指 令. 指 令 将 Rm 和 Rs 中 的 值 作 无 符 号 数 相 乘, 结 果 的 低 32 位 保 存 到 RsLo 中, 而 高 32 位 保 存 到 RdHi 中,. 指 令 格 式 如 下 : UMULL{cond}{S} RdLo,RdHi,Rm,Rs UMULL 指 令 举 例 如 下 : 第 25 页
UMULL R0,R1,R5,R8 ;(R1 R0)=R5 R8 UMLAL 64 位 无 符 号 乘 加 指 令. 指 令 将 Rm 和 Rs 中 的 值 作 无 符 号 数 相 乘,64 位 乘 积 与 RdHi,RdLo 相 加, 结 果 的 低 32 位 保 存 到 RdLo 中, 而 高 32 位 保 存 到 RdHi 中. 指 令 格 式 如 下 : UMLAL{cond}{S} RdLo,RdHi,Rm,Rs UMLAL 指 令 举 例 如 下 : UMLAL R0,R1,R5,R8 ;(R1,R0)=R5 R8+(R1,R0) SMULL 64 位 有 符 号 乘 法 指 令. 指 令 将 Rm 和 Rs 中 的 值 作 有 符 号 数 相 乘, 结 果 的 低 32 位 保 存 到 RdLo 中, 而 高 32 位 保 存 到 RdHi 中. 指 令 格 式 如 下 : SMULL{cond}{S} RdLo,RdHi,Rm,Rs SMULL 指 令 举 例 如 下 : SMULL R2,R3,R7,R6 ;(R3,R2)=R7 R6 SMLAL 64 位 有 符 号 乘 加 指 令. 指 令 将 Rm 和 Rs 中 的 值 作 有 符 号 数 相 乘,64 位 乘 积 与 RdHi,RdLo, 相 加, 结 果 的 低 32 位 保 存 到 RdLo 中, 而 高 32 位 保 存 到 RdHi 中. 指 令 格 式 如 下 : SMLAL{cond}{S} RdLo,RdHi,Rm,Rs SMLAL 指 令 举 例 如 下 : SMLAL R2,R3,R7,R6 ;(R3,R2)=R7 R6+(R3,R2) 第 26 页
ARM 跳 转 指 令 在 ARM 中 有 两 种 方 式 可 以 实 现 程 序 的 跳 转, 一 种 是 使 用 跳 转 指 令 直 接 跳 转, 另 一 种 则 是 直 接 向 PC 寄 存 器 赋 值 实 现 跳 转. 跳 转 指 令 有 跳 转 指 令 B, 带 链 接 的 跳 转 指 令 BL 带 状 态 切 换 的 跳 转 指 令 BX. 跳 转 指 令 助 记 符 说 明 操 作 条 件 码 位 置 B label 跳 转 指 令 Pc label B{cond} BL label 带 链 接 的 跳 转 指 令 LR PC-4, PC label BL{cond} BX Rm 带 状 态 切 换 的 跳 转 指 令 PC label, 切 换 处 理 状 态 BX{cond} B 跳 转 指 令. 跳 转 到 指 定 的 地 址 执 行 程 序. 指 令 格 式 如 下 ; B{cond} label 跳 转 指 令 B 举 例 如 下 : B WAITA ; 跳 转 到 WAITA 标 号 处 B 0x1234 ; 跳 转 到 绝 对 地 址 0x1234 处 跳 转 到 指 令 B 限 制 在 当 前 指 令 的 ±32Mb 的 范 围 内. BL 带 链 接 的 跳 转 指 令. 指 令 将 下 一 条 指 令 的 地 址 拷 贝 到 R14( 即 LR) 链 接 寄 存 器 中, 然 后 跳 转 到 指 定 地 址 运 行 程 序. 指 令 格 式 如 下 : BL{cond} label 带 链 接 的 跳 转 指 令 BL 举 例 如 下 : BL DELAY 跳 转 指 令 B 限 制 在 当 前 指 令 的 ±32MB 的 范 围 内.BL 指 令 用 于 子 程 序 调 用 BX 带 状 态 切 换 的 跳 转 指 令. 跳 转 到 Rm 指 定 的 地 址 执 行 程 序, 若 Rm 的 位 [0] 为 1, 则 跳 转 第 27 页
时 自 动 将 CPSR 中 的 标 志 T 置 位, 即 把 目 标 地 址 的 代 码 解 释 为 Thumb 代 码 ; 若 Rm 的 位 [0] 为 0, 则 跳 转 时 自 动 将 CPSR 中 的 标 志 T 复 位, 即 把 目 标 地 址 的 代 码 解 释 为 ARM 代 码. 指 令 格 式 如 下 : BX{cond} Rm 带 状 态 切 换 的 跳 转 指 令 BX 举 例 如 下 ADRL R0,ThumbFun+1 BX R0 ; 跳 转 到 R0 指 定 的 地 址, 并 根 据 R0 的 最 低 位 来 切 换 处 理 器 状 态 ARM 协 处 理 器 指 令 ARM 支 持 协 处 理 器 操 作, 协 处 理 器 的 控 制 要 通 过 协 处 理 器 命 令 实 现. ARM 协 处 理 器 指 令 助 记 符 说 明 操 作 条 件 码 位 置 CDP coproc,opcodel,crd,crn,crm{,opcode2} 协 处 理 器 数 据 操 作 指 令 取 决 于 协 处 理 器 CDP{cond} LDC{L} coproc,crd 地 址 协 处 理 器 数 据 读 取 指 令 取 决 于 协 处 理 器 LDC{cond}{L} STC{L} coproc,crd, 地 址 协 处 理 器 数 据 写 入 指 令 取 决 于 协 处 理 器 STC{cond}{L} MCR coproc, opcodel,rd,crn,{,opcode2} ARM 寄 存 器 到 协 处 理 器 寄 存 器 的 数 据 传 送 指 令 取 决 于 协 处 理 器 MCR{cond} MRC coproc, opcodel,rd,crn,{,opcode2} 协 处 理 器 寄 存 器 到 ARM 寄 存 器 到 数 据 传 送 指 令 取 决 于 协 处 理 器 MCR{cond} CDP 协 处 理 器 数 据 操 作 指 令.ARM 处 理 器 通 过 CDP 指 令 通 知 ARM 协 处 理 器 执 行 特 定 的 操 作. 该 操 作 由 协 处 理 器 完 成, 即 对 命 令 的 参 数 的 解 释 与 协 处 理 器 有 关, 指 令 的 使 用 取 决 于 协 处 理 器. 若 协 处 理 器 不 能 成 功 地 执 行 该 操 作, 将 产 生 未 定 义 指 令 异 常 中 断. 指 令 格 式 如 下 : CDP{cond} coproc,opcodel,crd,crn,crm{,opcode2} 其 中 : coproc 指 令 操 作 的 协 处 理 器 名. 标 准 名 为 pn,n 为 0~15. opcodel 协 处 理 器 的 特 定 操 作 码 CRd 作 为 目 标 寄 存 器 的 协 处 理 器 寄 存 器. CRN 存 放 第 1 个 操 作 数 的 协 处 理 器 寄 存 器. 第 28 页
CRm 存 放 第 2 个 操 作 数 的 协 处 理 器 寄 存 器. Opcode2 可 选 的 协 处 理 器 特 定 操 作 码. CDP 指 令 举 例 如 下 : CDP p7,0,c0,c2,c3,0 ; 协 处 理 器 7 操 作, 操 作 码 为 0, 可 选 操 作 码 为 0 CDP p6,1,c3,c4,c5 ; 协 处 理 器 操 作, 操 作 码 为 1 LDC 协 处 理 器 数 据 读 取 指 令.LDC 指 令 从 某 一 连 续 的 内 存 单 元 将 数 据 读 取 到 协 处 理 器 的 寄 存 器 中. 协 处 理 器 数 据 的 数 据 的 传 送, 由 协 处 理 器 来 控 传 送 的 字 数. 若 协 处 理 器 不 能 成 功 地 执 行 该 操 作, 将 产 生 未 定 义 指 令 异 常 中 断. 指 令 格 式 如 下 ; LDC{cond}{L} coproc,crd,< 地 址 > 其 中 : L 可 选 后 缀, 指 明 是 长 整 数 传 送. coproc 指 令 操 作 的 协 处 理 器 名. 标 准 名 为 pn,n 为 0~15 CRd 作 为 目 标 寄 存 的 协 处 理 器 寄 存 器. < 地 址 > 指 定 的 内 存 地 址 LDC 指 令 举 例 如 下 : LDC p5,c2,[r2,#4]; 读 取 R2+4 指 向 的 内 存 单 元 的 数 据, 传 送 到 协 处 理 器 p5 的 c2 寄 存 器 中 LDC p6,c2,[r1] ; 读 取 是 指 向 的 内 存 单 元 的 数 据, 传 送 到 协 处 理 器 p6 的 c2 寄 存 器 中 STC 协 处 理 器 数 据 写 入 指 令.STC 指 令 将 协 处 理 器 的 寄 存 器 数 据 写 入 到 某 一 连 续 的 内 存 单 元 中. 进 行 协 处 理 器 数 据 的 数 据 传 送, 由 协 处 理 器 来 控 制 传 送 的 字 数. 若 协 处 理 器 不 能 成 功 地 执 行 该 操 作, 将 产 生 未 定 义 指 令 异 常 中 断. 指 令 格 式 如 下 ; STC{cond}{L} coproc,crd,< 地 址 > 其 中 : L 可 选 后 缀, 指 明 是 长 整 数 传 送. coproc 指 令 操 作 的 协 处 理 器 名. 标 准 名 为 pn,n 为 0~15 CRd 作 为 目 标 寄 存 的 协 处 理 器 寄 存 器. 第 29 页
< 地 址 > 指 定 的 内 存 地 址 STC 指 令 举 例 如 下 : STC p5,c1,[r0] STC p5,c1,[ro,#-0x04] MCR ARM 寄 存 器 到 协 处 理 器 寄 存 器 的 数 据 传 送 指 令.MCR 指 令 将 ARM 处 理 器 的 寄 存 器 中 的 数 据 传 送 到 协 处 理 器 的 寄 存 器 中. 若 协 处 理 器 不 能 成 功 地 执 行 该 操 作, 将 产 生 未 定 义 指 令 异 常 中 断. 指 令 格 式 如 下 ; MCR{cond} coproc,opcodel,rd,crn,crm{,opcode2} 其 中 coproc 指 令 操 作 的 协 处 理 器 名. 标 准 名 为 pn,n 为 0~15. cpcodel 协 处 理 器 的 特 定 操 作 码. CRD 作 为 目 标 寄 存 器 的 协 处 理 器 寄 存 器. CRn 存 放 第 1 个 操 作 数 的 协 处 理 器 寄 存 器 MCR 指 令 举 例 如 下 : CRm 存 放 第 2 个 操 作 数 的 协 处 理 器 寄 存 器. Opcode2 可 选 的 协 处 理 器 特 定 操 作 码. MCR MCR p6,2,r7,c1,c2, P7,0,R1,c3,c2,1, MRC 协 处 理 器 寄 存 器 到 ARM 寄 存 器 到 的 数 据 传 送 指 令.MRC 指 令 将 协 处 理 器 寄 存 器 中 的 数 据 传 送 到 ARM 处 理 器 的 寄 存 器 中. 若 协 处 理 器 不 能 成 功 地 执 行 该 操 作. 将 产 生 未 定 义 异 常 中 断. 指 令 格 式 如 下. MRC {cond} coproc,opcodel,rd,crn,crm{,opcode2} 其 中 coproc 指 令 操 作 的 协 处 理 器 名. 标 准 名 为 pn,n, 为 0~15 opcodel 协 处 理 器 的 特 定 操 作 码. CRd 作 为 目 标 寄 存 器 的 协 处 理 器 寄 存 器. 第 30 页
CRn 存 放 第 1 个 操 作 数 的 协 处 理 器 寄 存 器. CRm 存 放 第 2 个 操 作 数 的 协 处 理 器 寄 存 器. opcode2 可 选 的 协 处 理 器 特 定 操 作 码. MRC 指 令 举 例 如 下 MRC p5,2,r2,c3,c2 MRC p7,0,r0,c1,c2,1 ARM 杂 项 指 令 助 记 符 说 明 操 作 条 件 码 位 置 SWI immed_24 软 中 断 指 令 产 生 软 中 断, 处 理 器 进 入 管 理 模 式 SWI{cond} MRS Rd,psr 读 状 态 寄 存 器 指 令 Rd psr,psr 为 CPSR 或 SPSR MRS{cond} MSR psr_fields,rd/#immed_8r 写 状 态 寄 存 器 指 令 psr_fields Rd/#immed_8r,psr 为 CPSR 或 SPSR MSR{cond} SWI 软 中 断 指 令.SWI 指 令 用 于 产 生 软 中 断, 从 而 实 现 在 用 户 模 式 变 换 到 管 理 模 式,CPSR 保 存 到 管 理 模 式 的 SPSR 中, 执 行 转 移 到 SWI 向 量, 在 其 它 模 式 下 也 可 使 用 SWI 指 令, 处 理 同 样 地 切 换 到 管 理 模 式. 指 令 格 式 如 下 ; SWI{cond} immed_24 其 中 immed_24 24 位 立 即 数, 值 为 0~16777215 之 间 的 整 数 SWI 指 令 举 例 如 下 : SWI 0 ; 软 中 断, 中 断 立 即 数 为 0 SWI 0x123456 ; 软 中 断, 中 断 立 即 数 为 0x123456 使 用 SWI 指 令 时, 通 常 使 用 以 下 两 种 方 法 进 行 传 递 参 数,SWI 异 常 中 断 处 理 程 序 就 可 以 提 供 相 关 的 服 务, 这 两 种 方 法 均 是 用 户 软 件 协 定.SWI 异 常 中 断 处 理 程 序 要 通 过 读 取 引 起 软 中 断 的 SWI 指 令, 以 取 得 24 位 立 即 数. 1. 指 令 24 位 的 立 即 数 指 定 了 用 户 请 求 的 服 务 类 型, 参 数 通 过 用 寄 存 器 传 递 MOV R0,#34 ; 设 置 了 功 能 号 为 34 SWI 12 ; 调 用 12 号 软 中 断 2. 指 令 中 的 24 位 立 即 数 被 忽 略, 用 户 请 求 的 服 务 类 型 由 寄 存 器 R0 的 值 决 定, 参 数 通 第 31 页
过 其 它 的 通 用 寄 存 器 传 递. MOV R0,#12 ; 调 用 12 号 软 中 断 MOV R1,#34 ; 设 置 子 功 能 号 为 34 SWI 0 在 SWI 异 常 中 断 处 理 程 序 中, 取 出 SWI 立 即 数 的 步 骤 为 : 首 先 确 定 引 起 软 中 断 的 SWI 指 令 是 ARM 指 令 还 时 Thumb 指 令, 这 可 通 过 对 SPSR 访 问 得 到 : 然 后 要 取 得 该 SWI 指 令 的 地 址, 这 可 通 过 访 问 LR 寄 存 器 得 到 : 接 着 读 出 指 令, 分 解 出 立 即 数. 读 出 SWI 立 即 数 T_bit EQU 0x20 SWI_Hander STMFD SP!,{R0_R3,R12,LR} ; 现 场 保 护 MRS R0,SPSR ; 读 取 SPSR STMFD SP!,{R0} ; 保 存 SPSR TST R0,#T_bit ; 测 试 T 标 志 位 LDRNEH R0,[LR,#-2] ; 若 是 Thumb 指 令, 读 取 指 令 码 (16 位 ) BICNE R0,R0,#0xFF00 ; 取 得 Thumb 指 令 的 8 位 立 即 数 LDREQ R0,[LR,#-4] ; 若 是 ARM 指 令, 读 取 指 令 码 (32 位 ) BICNQ R0,R0,#0xFF00000 ; 取 得 ARM 指 令 的 24 位 立 即 数 LDMFD SP!,{R0-R3,R12,PC}^ ;SWI 异 常 中 断 返 回 MRS 读 状 态 寄 存 器 指 令. 在 ARM 处 理 器 中, 只 有 MRS 指 令 可 以 状 态 寄 存 器 CPSR 或 SPSR 读 出 到 通 用 寄 存 器 中. 指 令 格 式 如 下 ; MRS{cond} Rd,psr 其 中 ; Rd 目 标 寄 存 器.Rd 不 允 许 为 R15. psr CPSR 或 SPSR SWI 指 令 举 例 如 下 MRS R1,CPSR ; 将 CPSR 状 态 寄 存 器 读 取, 保 存 到 R1 中 第 32 页
MRS R2,SPSR ; 将 SPSR 状 态 寄 存 器 读 取, 保 存 到 R2 中 MRS 指 令 读 取 CPSR, 可 用 来 判 断 ALU 的 状 态 标 志, 或 IRQ,FIQ 中 断 是 否 允 许 等 ; 在 异 常 处 理 程 序 中, 读 SPSR 可 知 道 进 行 异 常 前 的 处 理 器 状 态 等.MRS 与 MSR 配 合 使 用, 实 现 CPSR 或 SPSR 寄 存 器 的 读 修 改 --- 写 操 作, 可 用 来 进 行 处 理 器 模 式 切 换 (), 允 许? 禁 止 IRQ/FIQ 中 断 等 设 置. 另 外, 进 程 切 换 或 允 许 异 常 中 断 嵌 套 时, 也 需 要 使 用 MRS 指 令 读 取 SPSR 状 态 值. 保 存 起 来. 使 能 IRQ 中 断 ENABLE_IRQ MRS BIC MSR MOV R0,CPSR R0.R0,#0x80 CPSR_c,R0 PC,LR 禁 能 IRQ 中 断 DISABLE_IRQ MRS ORR MSR MOV R0,CPSR R0,R0,#0x80 CPSR_c,R0 PC,LR MSR 写 状 态 寄 存 器 指 令. 在 ARM 处 理 器 中. 只 有 MSR 指 令 可 以 直 接 设 置 状 态 寄 存 器 CPSR 或 SPSR. 指 令 格 式 如 下 MSR{cond} MSR{cond} psr_fields,#immed_8r psr_fields,rm 其 中 : psr CPSR 或 SPSR fields 指 定 传 送 的 区 域.Fields 可 以 是 以 下 的 一 种 或 多 种 ( 字 母 必 须 为 小 写 ): c 控 制 域 屏 蔽 字 节 (psr[70]) x 扩 展 域 屏 蔽 字 节 (psr[158]) s 状 态 域 屏 蔽 字 节 (psr[23.16]) 第 33 页
f 标 志 域 屏 蔽 字 节 (psr[3124]) immed_8r 要 传 送 到 状 态 寄 存 器 指 定 域 的 立 即 数,8 位. Rm 要 传 送 到 状 态 寄 存 器 指 定 域 的 数 据 的 源 寄 存 器. MSR 指 令 举 例 如 下 MSR CPSR_c,#0xD3 ;CPSR[70]=0xD3, 即 切 换 到 管 理 模 式. MSR CPSR_cxsf,R3 ;CPSR=R3 只 有 在 特 权 模 式 下 才 能 修 改 状 态 寄 存 器. 程 序 中 不 能 通 过 MSR 指 令 直 接 修 改 CPSR 中 的 T 控 制 位 来 实 现 ARM 状 态 /Thumb 状 态 的 切 换, 必 须 使 用 BX 指 令 完 成 处 理 器 状 态 的 切 换 ( 因 为 BX 指 令 属 转 移 指 令, 它 会 打 断 流 水 线 状 态, 实 现 处 理 器 状 态 切 换 ).MRS 与 MSR 配 合 使 用, 实 现 CPSR 或 SPSR 寄 存 器 的 读 --- 修 改 --- 写 操 作, 可 用 来 进 行 处 理 器 模 式 切 换 允 许 / 禁 止 IRQ/FIQ 中 断 等 设 置,. 堆 栈 指 令 实 始 化 INITSTACK MOV R0,LR ; 保 存 返 回 地 址 ; 设 置 管 理 模 式 堆 栈 MSR LDR CPSR_c,#0xD3 SP,StackSvc ; 设 置 中 断 模 式 堆 栈 MSR LDR CPSR_c,#0xD2 SP,StackIrq ARM 伪 指 令 ARM 伪 指 令 不 是 ARM 指 令 集 中 的 指 令, 只 是 为 了 编 程 方 便 编 译 器 定 义 了 伪 指 令, 使 用 时 可 以 像 其 它 ARM 指 令 一 样 使 用, 但 在 编 译 时 这 些 指 令 将 被 等 效 的 ARM 指 令 代 替.ARM 伪 指 令 有 四 条, 分 别 为 ADR 伪 指 令,ADRL 伪 指 令,LDR 伪 指 令,NOP 伪 指 令. 第 34 页
ADR 小 范 围 的 地 址 读 取 伪 指 令.ADR 指 令 将 基 于 PC 相 对 偏 移 的 地 址 值 读 取 到 寄 存 器 中. 在 汇 编 编 译 源 程 序 时,ADR 伪 指 令 被 编 译 器 替 换 成 一 条 合 适 的 指 令. 通 常, 编 译 器 用 一 条 ADD 指 令 或 SUB 指 令 来 实 现 该 ADR 伪 指 令 的 功 能, 若 不 能 用 一 条 指 令 实 现, 则 产 生 错 误, 编 译 失 败. ADR 伪 指 令 格 式 如 下 ADR{cond} register,exper 其 中 register 加 载 的 目 标 寄 存 器 exper 地 址 表 达 式. 当 地 址 值 是 非 字 地 齐 时, 取 值 范 围 -255~255 字 节 之 间 ; 当 地 址 是 字 对 齐 时, 取 值 范 围 -1020~1020 字 节 之 间. 对 于 基 于 PC 相 对 偏 移 的 地 址 值 时, 给 定 范 围 是 相 对 当 前 指 令 地 址 后 两 个 字 处 ( 因 为 ARM7TDMI 为 三 级 流 水 线 ). ADR 伪 指 令 举 例 如 下 ; LOOP MOV R1,#0xF0 ADR R2,LOOP ; 将 LOOP 的 地 址 放 入 R2 ADR R3,LOOP+4 可 以 用 ADR 加 载 地 址, 实 现 查 表 : ADR R0,DISP_TAB ; 加 载 转 换 表 地 址 LDRB R1,[R0,R2] ; 使 用 R2 作 为 参 数, 进 行 查 表 DISP_TAB DCB 0Xc0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90 ADRL 中 等 范 围 的 地 址 读 取 伪 指 令.ADRL 指 令 将 基 于 PC 相 对 偏 移 的 地 址 值 或 基 于 寄 存 器 相 对 偏 移 的 地 址 值 读 取 到 寄 存 器 中, 比 ADR 伪 指 令 可 以 读 取 更 大 范 围 的 地 址 在 汇 编 编 第 35 页
译 源 程 序 时,ADRL 伪 指 令 被 编 译 器 替 换 成 两 个 条 合 适 的 指 令 若 不 能 用 两 条 指 令 实 现 ADRL 伪 指 令 功 能, 则 产 生 错 误, 编 译 失 败 ADRL 伪 指 令 格 式 如 下 : ADR{cond} register,exper 其 中 :register 加 载 的 目 标 寄 存 器 expr 地 址 表 达 式 当 地 址 值 是 非 字 对 齐 时, 取 范 围 -64K~64K 字 节 ADRL 伪 指 令 举 例 如 下 ; 之 间 ; 当 地 址 值 是 字 对 齐 时, 取 值 范 围 -256K~256K 字 节 之 间 ADRL R0,DATA_BUF ADRL R1 DATA_BUF+80 DATA_BUF SPACE 100 ; 定 义 100 字 节 缓 冲 区 可 以 且 用 ADRL 加 载 地 址, 实 现 程 序 跳 转, 中 等 范 围 地 址 的 加 载 ADR LR,RETURNI ; 设 置 返 回 地 址 ADRL R1 Thumb_Sub+1; 取 得 了 Thumb 子 程 序 入 口 地 址, 且 R1 的 0 位 置 1 BX R1 ; 调 用 Thumb 子 程 序, 并 切 换 处 理 器 状 态 RETURNI CODE16 Thumb_Sub MOV R1,#10 LDR 大 范 围 的 地 址 读 取 伪 指 令.LDR 伪 指 令 用 于 加 载 32 位 的 立 即 数 或 一 个 地 址 值 到 指 定 寄 存 器. 在 汇 编 编 译 源 程 序 时,LDR 伪 指 令 被 编 译 器 替 换 成 一 条 合 适 的 指 令. 若 加 载 的 常 数 未 超 出 MOV 或 MVN 的 范 围, 则 使 用 MOV 或 MVN 指 令 代 替 该 LDR 伪 指 令, 否 则 汇 编 器 将 常 第 36 页
量 放 入 字 池, 并 使 用 一 条 程 序 相 对 偏 移 的 LDR 指 令 从 文 字 池 读 出 常 量.LDR 伪 指 令 格 式 如 下 ; LDR{cond} register,=expr/label_expr 其 中 register 加 载 的 目 标 寄 存 器 expr 32 位 立 即 数. label_expr 基 于 PC 的 地 址 表 达 式 或 外 部 表 达 式. LADR 伪 指 令 举 例 如 下. LDR R0,=0x123456 ; 加 载 32 位 立 即 数 0x12345678 LDR R0,=DATA_BUF+60 ; 加 载 DATA_BUF 地 址 +60 LTORG ; 声 明 文 字 池 伪 指 令 LDR 常 用 于 加 载 芯 片 外 围 功 能 部 件 的 寄 存 器 地 址 (32 位 立 即 数 ), 以 实 现 各 种 控 制 操 作 加 载 32 位 立 即 数 LDR R0,=IOPIN ; 加 载 GPIO 寄 存 器 IOPIN 的 地 址 LDR R1,[R0] ; 读 取 IOPIN 寄 存 器 的 值 LDR LDR R0,=IOSET R1,=0x00500500 STR R1,[R0] ;IOSET=0x00500500 从 PC 到 文 字 池 的 偏 移 量 必 须 小 于 4KB 与 ARM 指 令 的 LDR 相 比, 伪 指 令 的 LDR 的 参 数 有 = 号 NOP 空 操 作 伪 指 令.NOP 伪 指 令 在 汇 编 时 将 会 被 代 替 成 ARM 中 的 空 操 作, 比 如 可 能 为 MOV,R0,R0 指 令 等,NOP 伪 指 令 格 式 如 下 NOP 第 37 页
NOP 可 用 于 延 时 操 作. 软 件 延 时 DELAY1 NOP NOP NOP SUBS R1,R1,#1 BNE DELAY1 第 38 页
Thumb 指 令 集 Thumb 指 令 可 以 看 作 是 ARM 指 令 压 缩 形 式 的 子 集, 是 针 对 代 码 密 度 的 问 题 而 提 出 的, 它 具 有 16 位 的 代 码 密 度.Thumb 不 是 一 个 完 整 的 体 系 结 构, 不 能 指 望 处 理 只 执 行 Thumb 指 令 而 不 支 持 ARM 指 令 集. 因 此,Thumb 指 令 只 需 要 支 持 通 用 功 能, 必 要 时 可 以 借 助 于 完 善 的 ARM 指 令 集, 比 如, 所 有 异 常 自 动 进 入 ARM 状 态. 在 编 写 Thumb 指 令 时, 先 要 使 用 伪 指 令 CODE16 声 明, 而 且 在 ARM 指 令 中 要 使 用 BX 指 令 跳 转 到 Thumb 指 令, 以 切 换 处 理 器 状 态. 编 写 ARM 指 令 时, 则 可 使 用 伪 指 令 CODE32 声 明. Thumb 指 令 集 与 ARM 指 令 集 的 区 别 Thumb 指 令 集 没 有 协 处 理 器 指 令, 信 号 量 指 令 以 及 访 问 CPSR 或 SPSR 的 指 令, 没 有 乘 加 指 令 及 64 位 乘 法 指 令 等, 且 指 令 的 第 二 操 作 数 受 到 限 制 ; 除 了 跳 转 指 令 B 有 条 件 执 行 功 能 外, 其 它 指 令 均 为 无 条 件 执 行 ; 大 多 数 Thumb 数 据 处 理 指 令 采 用 2 地 址 格 式.Thumb 指 令 集 与 ARM 指 令 的 区 别 一 般 有 如 下 几 点 : 跳 转 指 令 程 序 相 对 转 移, 特 别 是 条 件 跳 转 与 ARM 代 码 下 的 跳 转 相 比, 在 范 围 上 有 更 多 的 限 制, 转 向 子 程 序 是 无 条 件 的 转 移. 数 据 处 理 指 令 数 据 处 理 指 令 是 对 通 用 寄 存 器 进 行 操 作, 在 大 多 数 情 况 下, 操 作 的 结 果 须 放 入 其 中 一 个 操 作 数 寄 存 器 中, 而 不 是 第 3 个 寄 存 器 中. 数 据 处 理 操 作 比 ARM 状 态 的 更 少, 访 问 寄 存 器 R8~R15 受 到 一 定 限 制. 除 MOV 和 ADD 指 令 访 问 器 R8~R15 外, 其 它 数 据 处 理 指 令 总 是 更 新 CPSR 中 的 ALU 状 态 标 志. 访 问 寄 存 器 R8~R15 的 Thumb 数 据 处 理 指 令 不 能 更 新 CPSR 中 的 ALU 状 态 标 志. 单 寄 存 器 加 载 和 存 储 指 令 在 Thumb 状 态 下, 单 寄 存 器 加 载 和 存 储 指 令 只 能 访 问 寄 存 器 R0~R7 批 量 寄 存 器 加 载 和 存 储 指 令 LDM 和 STM 指 令 可 以 将 任 何 范 围 为 R0~R7 的 寄 存 器 子 集 加 载 或 存 储. 第 39 页
PUSH 和 POP 指 令 使 用 堆 栈 指 令 R13 作 为 基 址 实 现 满 递 减 堆 栈. 除 R0~R7 外,PUSH 指 令 还 可 以 存 储 链 接 寄 存 器 R14, 并 且 POP 指 令 可 以 加 载 程 序 指 令 PC Thumb 存 储 器 访 问 指 令 Thumb 指 令 集 的 LDM 和 SRM 指 令 可 以 将 任 何 范 围 为 R0~R7 的 寄 存 器 子 集 加 载 或 存 储. 批 量 寄 存 器 加 载 和 存 储 指 令 只 有 LDMIA,STMIA 指 令, 即 每 次 传 送 先 加 载 / 存 储 数 据, 然 后 地 址 加 4. 对 堆 栈 处 理 只 能 使 用 PUSH 指 令 及 POP 指 令. Thumb 存 储 器 访 问 指 令 助 记 符 说 明 操 作 影 响 标 志 LDR Rd,[Rn,#immed_5 4] 加 载 字 数 据 Rd [Rm,#immed_5 4],Rd,Rn 为 R0~R7 无 LDRH Rd,[Rn,#immed_5 2] 加 载 无 符 半 字 数 据 Rd [Rm,#immed_5 2],Rd,Rn 为 R0~R7 无 LDRB Rd,[Rn,#immed_5 1] 加 载 无 符 字 节 数 据 Rd [Rm,#immed_5 1],Rd,Rn 为 R0~R7 无 STR Rd,[Rn,#immed_5 4] 存 储 字 数 据 Rn,#immed_5 4Rd Rd,Rn 为 R0~R7 无 STRH Rd,[Rn,#immed_5 2] 存 储 无 符 半 辽 数 据 Rn,#immed_5 2]Rd Rd,Rn 为 R0~R7 无 STRB Rd,[Rn#immed_5 1] 存 储 无 符 字 节 数 据 Rn,#immed_5 1]Rd Rd,Rn 为 R0~R7 无 LDR Rd,[Rn,Rm] 加 载 字 数 据 Rd [Rn,Rm],Rd,Rn,Rm 为 R0~R7 无 LDRH Rd,[Rn,Rm] 加 载 无 符 半 字 数 据 Rd [Rn,Rm],Rd,Rn,Rm 为 R0~R7 无 LDRB Rd,[Rn,Rm] 加 载 无 符 字 节 数 据 Rd [Rn,Rm],Rd,Rn,Rm 为 R0~R7 无 LDRSH Rd[Rn,Rm] 加 载 有 符 半 字 数 据 Rd [Rn,Rm],Rd,Rn,Rm 为 R0~R7 无 LDRSB Rd[Rn,Rm] 加 载 有 符 字 节 数 据 Rd [Rn,Rm],Rd,Rn,Rm 为 R0~R7 无 STR Rd,[Rn,Rm] 存 储 字 数 据 [Rn,Rm] Rd,Rd,Rn,Rm 为 R0~R7 无 STRH Rd,[Rn,Rm] 存 储 无 符 半 字 数 据 [Rn,Rm] Rd,Rd,Rn,Rm 为 R0~R7 无 STRB Rd,[Rn,Rm] 存 储 无 符 字 节 数 据 [Rn,Rm] Rd,Rd,Rn,Rm 为 R0~R7 无 LDR Rd,[PC,#immed_8 4] 基 于 PC 加 载 字 数 据 Rd {PC,#immed_8 4]Rd 为 R0~R7 无 LDR Rd,label 基 于 PC 加 载 字 数 据 Rd [label],rd 为 R0~R7 无 LDR Rd,[SP,#immed_8 4] 基 于 SP 加 载 字 数 据 Rd {SP,#immed_8 4]Rd 为 R0~R7 无 STR Rd,[SP,#immed_8 4] 基 于 SP 存 储 字 数 据 {SP,#immed_8 4] Rd,Rd 为 R0~R7 无 LDMIA Rn{!}reglist 批 量 ( 寄 存 器 ) 加 载 regist [Rn],Rn 回 存 等 (R0~R7) 无 STMIA Rn{!}reglist 批 量 ( 寄 存 器 ) 加 载 [Rn] reglist,rn 回 存 等 (R0~R7) 无 PUSH {reglist[,lr]} 寄 存 器 入 栈 指 令 [SP] reglist[,lr],sp 回 存 等 (R0~R7,LR) 无 POP {reglist[,pc]} 寄 存 器 入 栈 指 令 reglist[,pc] [SP],SP 回 存 等 (R0~R7,PC) 无 第 40 页
LDR 和 STR 立 即 数 偏 移 的 LDR 和 STR 指 令. 存 储 器 的 地 址 以 一 个 寄 存 器 的 立 即 数 偏 移 指 明. 指 令 格 式 如 下 : LDR STR Rd,[Rn,#immed_5 4]; 加 载 指 定 地 址 上 的 数 据 ( 字 ), 放 入 Rd 中 Rd,[Rn,#immed_5 4]; 存 储 数 据 ( 字 ) 到 指 定 地 址 的 存 储 单 元, 要 存 储 数 据 在 Rd 中 LDRH Rd,[Rn,#immed_5 4]; 加 载 半 字 数 据, 放 入 Rd 中, 即 Rd 低 16 位 有 效, 高 16 位 清 零 STRH Rd,[Rn,#immed_5 4]; 存 储 半 字 数 据, 要 存 储 的 数 据 在 Rd, 最 低 16 位 有 效 LDRB Rd,[Rn,#immed_5 4]; 加 载 字 节 数 据, 放 入 Rd 中, 即 Rd 最 低 字 节 有 效, 高 24 位 清 零 STRB Rd,[Rn,#immed_5 4]; 存 储 字 节 数 据, 要 存 储 的 数 据 在 Rd, 最 低 字 节 有 效 其 中 Rd 加 载 或 存 储 的 寄 存 器. 必 须 为 R0~R7. Rn 基 址 寄 存 器. 必 须 为 R0~R7. immed_5 N 偏 移 量. 它 是 一 个 无 符 立 即 数 表 达 式, 其 取 值 为 (0~3) N 立 即 数 偏 移 的 半 字 和 字 节 加 载 是 无 符 号 的. 数 据 加 载 到 Rd 的 最 低 有 效 半 字 或 字 节,Rd 的 其 余 位 补 0. 地 址 对 准 一 一 字 传 送 时, 必 须 保 证 传 送 地 址 为 32 位 对 准. 半 字 传 送 时, 必 须 保 证 传 送 地 址 为 16 位 对 准 立 即 数 偏 移 的 LDR 和 STR 指 令 举 例 如 下 ; LDR STR R0,[R1,#0x4] R3,[R4] LDRH R5,[R0,#0x02] STRH R1,[R0,#0x08] LDRB R3,[R6,#20] STRB R1,[R0,#31] 寄 存 器 偏 移 的 LDR 和 STR 指 令. 存 储 器 的 地 址 用 一 个 寄 存 器 的 基 于 寄 存 器 偏 移 来 指 明. 指 令 格 式 如 下, LDR Rd,[Rn,Rm] ; 加 载 一 个 字 数 据 STR Rd,[Rn,Rm] ; 存 储 一 个 字 数 据 LDRH Rd,[Rn,Rm] ; 加 载 一 个 无 符 半 字 数 据 第 41 页
STRH Rd,[Rn,Rm] ; 存 储 一 个 无 符 半 字 数 据 LDRB Rd,[Rn,Rm] ; 加 载 一 个 无 符 字 节 数 据 STRB Rd,[Rn,Rm] ; 存 储 一 个 无 符 字 节 数 据 LDRSH Rd,[Rn,Rm] LDRSB Rd,[Rn,Rm] ; 加 载 一 个 有 符 半 字 数 据 ; 存 储 一 个 有 符 半 字 数 据 其 中 : Rd 加 载 或 存 储 的 寄 存 器. 必 须 为 R0~R7 Rn 基 址 寄 存 器. 必 须 为 R0~R7 Rm 内 含 偏 移 量 的 寄 存 器. 必 须 为 R0~R7. 寄 存 器 偏 移 的 半 字 和 字 节 加 载 可 以 是 有 符 号 或 无 符 号 的, 数 据 加 载 到 Rd 的 其 余 位 拷 贝 符 号 位. 地 址 对 准 字 传 送 时, 必 须 保 证 传 送 地 址 为 32 位 对 准. 半 字 传 送 时, 必 须 保 证 传 送 地 址 为 16 位 对 准. 寄 存 器 偏 移 的 LDR 和 STR 指 令 举 例 如 下 ; LDR STR LDRH STRH LDRB STRB LDRSH LDRSB R3,[R1,R0] R1,[R0,R2] R6,[R0,R1] R0,[R4,R5] R2,[R5,R1] R1,[R3,R2] R7,[R6,R3] R5,[R7,R2] PC 或 SP 相 对 偏 移 的 LDR 和 STR 指 令. 用 PC 或 SP 寄 存 器 中 的 值 的 立 即 数 偏 移 来 指 明 存 储 器 的 地 址. 指 令 格 式 如 下. LDR LDR LDR STR Rd,[PC,#immed_8 4] Rd,label Rd,[SP,#immed_8 4] Rd,[SP,#immed_8 4] 其 中 : Rd 加 载 或 存 储 的 寄 存 器. 必 须 为 R0~R7 immed_8 4] 偏 移 量. 它 是 一 个 无 符 立 即 数 表 达 式, 其 取 值 为 (0~255) 4 第 42 页
label 程 序 相 对 偏 移 表 达 式.label 必 须 在 当 前 指 令 之 后 IK 字 节 范 围 内. 地 址 对 准 地 址 必 须 是 4 的 整 数 倍. PC 或 SP 相 对 偏 移 的 LDR 和 STR 指 令 举 例 如 下 ; LDR R0,[PC,#0x08] ; 读 取 PC+0x08 地 址 上 的 字 数 据, 保 存 到 R0 中 LDR R7,LOCALDAT ; 读 取 LOCALDAT 地 址 上 的 字 数 据, 保 存 到 R7 中 LDR R3,[SP,#1020] ; 读 取 SP+1020 地 址 上 的 字 数 据, 保 存 到 R3 中 STR R2,[SP] ; 存 储 R2 寄 存 器 的 数 据 到 SP 指 向 的 存 储 单 元 ( 偏 移 量 为 0) PUSH 和 POP 寄 存 器 入 栈 及 出 栈 指 令. 实 现 低 寄 存 器 和 可 选 的 LR 寄 存 器 入 栈 寄 存 器 和 可 选 的 PC 寄 存 器 出 栈 操 作, 堆 栈 地 址 由 SP 寄 存 设 置, 堆 栈 是 满 递 减 堆 栈. 指 令 格 式 如 下 ; PUSH POP {reglist[,lr]} {reglist[,pc]} 其 中 reglist 入 栈 / 出 栈 低 寄 存 器 列 表, 即 R0~R7 LR PC 入 栈 时 的 可 选 寄 存 器 出 栈 时 的 可 选 寄 存 器 寄 存 器 入 栈 及 出 栈 指 令 举 例 如 下 ; PUSH {R0-R7,LR} ; 将 低 寄 存 器 R0~R7 全 部 入 栈,LR 也 入 栈 POP {R0-R7,PC} ; 将 堆 栈 中 的 数 据 弹 出 到 低 寄 存 器 R0~R7 及 PC 中 LDMIA 和 STMIA 批 量 加 载 / 存 储 指 令 可 以 实 现 在 一 组 寄 存 器 和 一 块 连 续 的 内 存 单 元 之 间 传 输 数 据.Thumb 指 令 集 批 量 加 载 / 存 储 指 令 为 LDMIA 和 STMIA,LDMIA 为 加 载 多 个 寄 存 器 ;STM 为 存 储 多 个 寄 存 器, 允 许 一 条 指 令 传 送 8 个 低 寄 存 器 的 任 何 子 集. 指 令 格 式 如 下 ; LDMIA STMIA Rn!,reglist Rn!,reglist 其 中 Rn 加 载 / 存 储 的 起 始 地 址 寄 存 器.Rn 必 须 为 R0~R7 Reglist 加 载 / 存 储 的 寄 存 器 列 表. 寄 存 器 必 须 为 R0~R7 第 43 页
LDMIA/STMIA 的 主 要 用 途 是 数 据 复 制, 参 数 传 送 等, 进 行 数 据 传 送 时, 每 次 传 送 后 地 址 加 4. 若 Rn 在 寄 存 器 列 表 中, 对 于 LDMIA 指 令,Rn 的 最 终 值 是 加 载 的 值, 而 不 是 增 加 后 的 地 址 ; 对 于 STMIA 指 令, 在 Rn 是 寄 存 器 列 表 中 的 最 低 数 字 的 寄 存 器, 则 Rn 存 储 的 值 为 Rn 在 初 值, 其 它 情 况 不 可 预 知. 批 量 加 载 / 存 储 指 令 举 例 如 下 ; LDMIA R0,{R2-R7} ; 加 载 R0 指 向 的 地 址 上 的 多 字 数 据, 保 存 到 R2~R7 中,R0 的 值 更 新. STMIA R1!,{R2-R7}; 将 R2~R7 的 数 据 存 储 到 R1 指 向 的 地 址 上,R1 值 更 新. 第 44 页
Thumb 数 据 处 理 指 令 大 多 数 Thumb 处 理 指 令 采 用 2 地 址 格 式, 数 据 处 理 操 作 比 ARM 状 态 的 更 少, 访 问 寄 存 器 R8~R15 受 到 一 定 限 制. Thumb 数 据 处 理 指 令 助 记 符 说 明 操 作 影 响 标 志 MOV Rd,#expr 数 据 转 送 Rd expr,rd 为 R0~R7 影 响 N,Z MOV Rd,Rm 数 据 转 送 Rd Rm,Rd Rm 均 可 为 R0~R15 RdT 和 Rm 均 为 R0~R7 时, 影 响 N,Z, 清 零 C,V MVN Rd,Rm 数 据 非 传 送 指 令 Rd (~Rm),Rd,Rm 均 为 R0~R7 影 响 N,Z NEG Rd,Rm 数 据 取 负 指 令 Rd (-Rm),Rd,Rm 均 为 R0~R7 影 响 N,Z,C,V ADD Rd.Rn,Rm 加 法 运 算 指 令 Rd Rn+Rm,Rd,Rn,Rm 均 为 R0~R7 影 响 N,Z,C,V ADD Rd.Rn,#expr3 加 法 运 算 指 令 Rd Rn+expr#,Rd,Rn 均 为 R0~R7 影 响 N,Z,C,V ADD Rd,#expr8 加 法 运 算 指 令 Rd Rd+expr8,Rd 为 R0~R7 影 响 N,Z,C,V ADD Rd,Rm 加 法 运 算 指 令 Rd Rd+Rm,Rd,Rm 均 可 为 R0~R15 ADD Rd,Rp#expr SP/PC 加 法 运 算 指 令 Rd SP+expr 或 PC+expr,Rd 为 R0~R7 无 ADD SP,#expr SP 加 法 运 算 指 令 SP SP+expr 无 Rd 和 Rm 均 为 R0~ R7 N,Z,C,V 时, 影 响 SUB Rd,Rn,Rm 减 法 运 算 指 令 Rd Rn-Rm,Rd Rn Rm 均 为 R0~R7 影 响 N,Z,C,V SUB Rd,Rn#expr3 减 法 运 算 指 令 Rd Rn-expr3,RdRn 均 为 R0~R7 影 响 N,Z,C,V SUB Rd,#expr8 减 法 运 算 指 令 RD Rd-expr8,Rd 为 R0~R7 影 响 N,Z,C,V SUB SP,#expr SP 减 法 运 算 指 令 SP SP-expr 无 ADC Rd,Rm 带 进 位 加 法 指 令 Rd Rd+Rm+Carry,Rd Rm 为 R0~R7 影 响 N,Z,C,V SBC Rd,Rm 带 位 减 法 指 令 Rd Rd-Rm-(NOT)Carry,Rd Rm 为 R0~R7 影 响 N,Z,C,V MUL Rd,Rm 乘 法 运 算 指 令 Rd Rd*Rm,Rd Rm 为 R0~R7 影 响 N,Z, AND Rd,Rm 逻 辑 与 操 作 指 令 Rd Rd&Rm,Rd Rm 为 R0~R7 影 响 N,Z, ORR Rd,Rm 逻 辑 或 操 作 指 令 Rd Rd Rm,Rd Rm 为 R0~R7 影 响 N,Z, EOR Rd,Rm 逻 辑 异 或 操 作 指 令 Rd Rd^Rm,Rd Rm 为 R0~R7 影 响 N,Z, BIC Rd,Rm 位 清 除 指 令 Rd Rd&(~Rm),Rd Rm 为 R0~R7 影 响 N,Z, ASR Rd,Rs 算 术 右 移 指 令 Rd Rd 算 术 右 移 Rs 位,Rd,Rs 为 R0~R7 影 响 N,Z,C, ASR Rd,Rm#expr 算 术 右 移 指 令 Rd Rm 算 术 右 移 expr 位,Rd Rm 为 R0~R7 影 响 N,Z,C, LSL Rd,Rs 逻 辑 左 移 指 令 Rd Rd<<Rs,Rd Rs 为 R0~R7 影 响 N,Z,C, LSL Rd,Rm,#expr 逻 辑 左 移 指 令 Rd Rm<<expr,Rd Rm 为 R0~R7 影 响 N,Z,C, LSR Rd,Rs 逻 辑 右 移 指 令 Rd Rd>>Rs,Rd Rs 为 R0~R7 影 响 N,Z,C, LSR Rd,Rm,#expr 逻 辑 右 移 指 令 Rd Rm>>mexpr,Rd Rm 为 R0~R7 影 响 N,Z,C, ROR Rd,Rs 循 环 右 移 指 令 Rd Rm 循 环 右 移 Rs 位,Rd Rs 为 R0~R7 影 响 N,Z,C, CMP Rn,Rm 比 较 指 令 状 态 标 Rn-Rm,Rn Rm 为 R0~R15 影 响 N,Z,C,V CMP Rn,#expr 比 较 指 令 状 态 标 Rn-expr,Rn 为 R0~R7 影 响 N,Z,C,V CMN Rn,Rm 负 数 比 较 指 令 ] 状 态 标 Rn+Rm,Rn Rm 为 R0~R7 影 响 N,Z,C,V 第 45 页
TST Rn,Rm 位 测 试 指 令 状 态 标 Rn&Rm,Rn Rm 为 R0~R7 影 响 N,Z,C,V 数 据 传 送 指 令 MOV 式 如 下 ; 数 据 传 送 指 令. 将 8 位 立 即 数 或 寄 存 器 (operand2) 传 送 到 目 标 寄 存 器 (Rd). 指 令 格 MOV MOV Rd,#expr Rd,Rm 其 中 Rd 目 标 寄 存 器.MOV Rd#expr 时, 必 须 在 R0~R7 之 间 exper 8 位 立 即 数, 即 0~255 Rm 源 寄 存 器. 为 R0~R15 条 件 码 标 志 : MOV Rd,#expr 指 令 会 更 新 N 和 Z 标 志, 对 标 志 C 和 V 无 影 响. 而 MOV,Rd,Rm 指 令, 若 Rd 或 Rm 是 高 寄 存 器 (R8~R15), 则 标 志 不 受 影 响, 若 Rd 或 Rm 都 是 低 寄 存 器 (R0~R7), 则 会 更 新 N 和 Z, 且 清 除 标 志 C 和 V. MOV 指 令 举 例 如 下 MOV R1,#0x10 ;R1=0x10 MOV R0,R8 ;R0=R8 MOV PC,LR ;PC=LR, 子 程 序 返 回 MVN 数 据 非 传 送 指 令. 将 寄 存 器 Rm 按 位 取 反 后 传 送 到 目 标 寄 存 器 (Rd). 指 令 格 式 如 下 : MVN Rd,Rm 其 中 : Rd 目 标 寄 存 器. 必 须 在 R0~R7 之 间 Rm 源 寄 存 器. 必 须 在 R0~R7 之 间 条 件 码 标 志 : 指 令 会 更 新 N 和 Z 标 志, 对 标 志 C 和 V 无 影 响. MVN 指 令 举 例 如 下 MVN R1,R2 ; 将 R2 取 反 结 果 存 到 R1 第 46 页
NEG 数 据 取 负 指 令. 将 寄 存 器 Rm 乘 以 -1 后 传 送 到 目 标 寄 存 器 (Rd). 指 令 格 式 如 下 : NEG Rd,Rm 其 中 : Rd 目 标 寄 存 器. 必 须 在 R0~R7 之 间 Rm 源 寄 存 器. 必 须 在 R0~R7 之 间 条 件 码 标 志 指 令 会 更 新 N,Z,C,V 和 标 志. NEG 指 令 举 例 如 下 NEG R1,R0, ;R1=-R0 算 术 逻 辑 运 算 指 令 ADD 加 法 运 算 指 令. 将 两 个 数 据 相 加, 结 果 保 存 到 Rd 寄 存 器. 低 寄 存 器 的 ADD 指 令 的 指 令 格 式 如 下 ADD ADD ADD Rd,Rn,Rm Rd,Rn,#expr3 Rd,#expr8 其 中 Rd 目 标 寄 存 器. 必 须 在 R0~R7 之 间. Rn 第 一 个 操 作 数 寄 存 器. 必 须 在 R0~R7 之 间. Rm 第 二 个 操 作 数 寄 存 器. 必 须 在 R0~R7 之 间. expr3 3 位 立 即 数, 即 0~7 expr8 8 位 立 即 数, 即 0~255. 条 件 码 标 志 : 指 令 会 更 新 N Z C 和 V 标 志. 高 或 低 寄 存 器 的 ADD 指 令 的 指 令 格 式 如 下 : ADD Rd,Rm 其 中 Rd 目 标 寄 存 器, 也 是 第 一 个 操 数 寄 存 器. Rm 第 二 个 操 作 数 寄 存 器 条 件 码 标 志 : 若 Rd 或 Rm 都 是 低 寄 存 器 (R0~R7), 指 令 会 更 新 N Z C 和 V 标 志. 其 它 情 况 不 影 响 条 件 码 标 志. 第 47 页
PC 或 SP 相 对 偏 移 的 ADD 指 令 指 令 格 式 如 下 : ADD Rd,Rp,#expr 其 中 Rd 目 标 寄 存 器. 必 须 在 R0~R7 之 间 Rp PC 或 SP, 第 一 个 操 作 数 寄 存 器. expr 立 即 数, 在 0~1020 范 围 内. 条 件 码 标 志 : 不 影 响 条 件 码 标 志. SP 操 作 的 ADD 指 令 的 指 令 格 式 如 下 ADD ADD SP,#expr SP,SP,#expr 其 中 SP 目 标 寄 存 器, 也 是 第 一 个 操 作 数 寄 存 器. expr 立 即 数, 在 -508~+508 之 间 的 4 的 整 数 倍 的 数 条 件 码 标 志 : 不 影 响 条 件 码 标 志. ADD 指 令 举 例 如 下 ADD R1,R1,R0 ;R1=R1+R0 ADD R1,R1,#7 ;R1=R1+7 ADD R3,#200 ;R3=R3+200 ADD R3,R8 ;R3=R3+R8 ADD ADD R1,SP,#1000 ;R1=SP+1000 SP,SP,#-500 ;SP=SP-500 SUB 减 法 运 算 指 令. 将 两 个 数 相 减, 结 果 保 存 到 Rd 中. 低 寄 存 器 的 SUB 指 令 的 指 令 格 式 如 下 ; SUB Rd,Rn,Rm SUB Rd,Rn,#expr3 SUB Rd,#expr8 其 中 Rd 目 标 寄 存 器. 必 须 在 R0~R7 之 间 Rn Rm 第 一 个 操 作 数 寄 存 器. 必 须 在 R0~R7 之 间 第 一 个 操 作 数 寄 存 器. 必 须 在 R0~R7 之 间 expr3 3 位 立 即 数, 即 0~7 第 48 页
expr8 8 位 立 即 数. 即 0~255 条 件 码 标 志 : 指 令 会 更 新 N Z C 和 V 标 志. SP 操 作 的 SUB 指 令 的 指 令 格 式 如 下 SUB SP,#expr SUB SP,SP,#expr 其 中 SP 目 标 寄 存 器, 也 是 第 一 个 操 作 数 据 寄 存 器. expr 立 即 数, 在 -508~+508 之 间 的 4 的 整 数 倍 的 数 条 件 码 标 志 : 不 影 响 条 件 码 标 志 SUB 指 令 举 例 如 下 SUB R0,R2,R1, SUB R2,R1,#1 SUB R6,#250 SUB SP,#380 ;R0=R2-R1 ;R2=R1-1 ;R6=R6-250 ;SP=SP-380 ADC 带 进 位 加 法 指 令. 将 Rm 的 值 与 Rd 的 值 相 加, 再 加 上 CPSR 中 的 C 条 件 标 志 位, 结 果 保 存 到 Rd 寄 存 器. 指 令 格 式 如 下 ADC Rd,Rm 其 中 Rd Rm 目 标 寄 存 器, 也 是 第 一 个 操 作 数 寄 存 器. 必 须 在 R0~R7 之 间 第 二 个 操 作 数 寄 存 器. 必 须 在 R0~R7 之 间 条 件 码 标 志 : 指 令 会 更 新 N Z C 和 V 标 志. ADC 指 令 举 例 如 下 ; ADD R0,R0,R2, ADC R1,R1,R3 ; 使 用 ADC 实 现 64 位 加 法,(R1,R0)+(R3,R2) SBC 带 进 位 减 法 指 令. 用 寄 存 器 Rd 减 去 Rm, 再 减 去 CPSR 中 的 C 条 件 标 志 的 非 ( 即 若 C 标 志 清 零, 则 结 果 减 去 1), 结 果 保 存 到 Rd 中. 指 令 格 式 如 下 SBC Rd,Rm 其 中 Rd 目 标 寄 存 器, 也 是 第 一 个 操 作 数 寄 存 器. 必 须 在 R0~R7 之 间 第 49 页
Rm 第 二 个 操 作 数 寄 存 器. 必 须 在 R0~R7 之 间 ] 条 件 码 标 志 : 指 令 会 更 新 N Z C 和 V 标 志 SBC 指 令 举 例 如 下 SUB R0,R0,R2 SUB R1,R1,R3 ; 使 用 SBC 实 现 64 位 减 法,(R1,R0)=(R1,R0)-(R3,R2) MUL 乘 法 运 算 指 令. 用 寄 存 器 Rd 乘 以 Rm, 结 果 保 存 到 Rd 中. 指 令 格 式 如 下 ; MUL Rd,Rm 其 中 Rd 目 标 寄 存 器, 也 是 第 一 个 操 作 数 寄 存 器. 必 须 在 R0~R7 之 间 Rm 第 二 操 作 数 寄 存 器. 必 须 在 R0~R7 之 间 条 件 码 标 志 : 指 令 会 更 新 N 和 Z 标 志 MUL 指 令 举 例 如 下 MUL R2,R0,R1 ;R2=R0*R1 AND 逻 辑 与 操 作 指 令. 将 寄 存 器 Rd 的 值 与 寄 存 器 Rm 值 按 位 作 逻 辑 与 操 作, 结 果 保 存 到 Rd 中. 指 令 格 式 如 下 AND Rd,Rm 其 中 Rd 目 标 寄 存 器, 也 是 第 一 个 操 作 数 寄 存 器. 必 须 在 R0~R7 之 间 Rm 第 二 个 操 作 数 寄 存 器. 必 须 在 R0~R7 之 间 条 件 码 标 志 : 指 令 会 更 新 N 和 Z 标 志 AND 指 令 举 例 如 下 ; MOV R1,#0x0F AND R0,R1 ;R0=R0 & R1 ORR 逻 辑 或 操 作 指 令. 将 寄 存 器 Rd 与 寄 存 器 Rn 的 值 按 位 作 逻 辑 或 操 作, 结 果 保 存 到 Rd 中. 指 令 格 式 如 下 : ORR Rd,Rm 其 中 Rd 目 标 寄 存 器, 也 是 第 一 个 操 作 数 寄 存 器. 必 须 在 R0~R7 之 间 第 50 页
Rm 第 二 个 操 作 数 寄 存 器. 必 须 在 R0~R7 之 间 条 件 码 标 志 : 指 令 会 更 新 N 和 Z 标 志 ORR 指 令 举 例 如 下 MOV R1,#0x03 ORR R0,R1 ;R0=R0 R1 EOR 逻 辑 异 或 操 作 指 令. 寄 存 器 Rd 的 值 与 寄 存 器 Rn 的 值 按 位 作 逻 辑 异 或 操 作, 结 果 保 存 到 Rd 中, 指 令 格 式 如 下 ; EOR 其 中 Rd,Rm Rd 目 标 寄 存 器, 也 是 第 一 个 操 作 数 寄 存 器. 必 须 在 R0~R7 之 间 Rm 第 二 个 操 作 数 寄 存 器. 必 须 在 R0~R7 之 间 条 件 码 标 志 : 指 令 会 更 新 N 和 Z 标 志 EOR 指 令 举 例 如 下 MOV R2,#0Xf0 EOR R3,R2, ;R3=R3^R2 BIC 位 清 除 指 令. 将 寄 存 器 Rd 的 值 与 寄 存 器 Rm 的 值 反 码 按 位 作 逻 辑 与 操 作. 结 果 保 存 到 Rd 中, 指 令 格 式 如 下 BIC Rd,Rm 其 中 Rd 目 标 寄 存 器, 也 是 第 一 个 操 作 数 寄 存 器. 必 须 在 R0~R7 之 间. Rm 第 二 个 操 作 数 寄 存 器. 必 须 在 R0~R7 之 间 条 件 码 标 志 : 指 令 会 更 新 N 和 Z 标 志 BIC 指 令 举 例 如 下 : MOV R1,#0x80 BIC R3,R1 ; 将 R1 的 最 高 位 清 零, 其 它 位 不 变 ASR 式 如 下 ; 算 术 右 移 指 令. 数 据 算 术 右 移, 将 符 号 位 拷 贝 到 空 位, 移 位 结 果 保 存 到 Rd 中, 指 令 格 第 51 页
ASR Rd,Rs ASR Rd,Rm,#expr 其 中 Rd Rs Rm 目 标 寄 存 器, 也 是 第 一 个 操 作 数 寄 存 器. 必 须 在 R0~R7 之 间 寄 存 器 控 制 移 位 中 包 含 移 位 量 的 寄 存 器. 必 须 在 R0~R7 之 间 立 即 数 移 位 的 源 寄 存 器. 必 须 在 R0~R7 之 间 expr 立 即 数 移 位 量, 值 为 1~32 条 件 码 标 志 : 指 令 会 更 新 N Z 和 C 标 志 ( 若 移 位 量 为 零, 则 不 影 响 C 标 志 ) ASR 指 令 举 例 如 下 ASR ASR R1,R2, R3,R1,#2 若 移 位 量 为 32, 则 Rd 清 零, 最 后 移 出 的 位 保 留 在 标 志 C 中, 若 移 位 量 大 于 32, 则 Rd 和 标 志 C 均 被 清 零 ; 若 移 位 量 为 0, 则 不 影 响 C 标 志 LSL 逻 辑 左 移 指 令. 数 据 逻 辑 左 移, 空 位 清 零, 移 位 结 果 保 存 到 Rd 中, 指 令 格 式 如 下 LSL LSL Rd,Rs Rd,Rm,#expr 其 中 Rd 目 标 寄 存 器, 也 是 第 一 个 操 作 数 寄 存 器. 必 须 在 R0~R7 之 间 Rs Rm 寄 存 器 控 制 移 位 中 包 含 位 量 的 寄 存 器. 必 须 在 R0~R7 之 间 立 即 数 移 位 的 源 寄 存 器. 必 须 在 R0~R7 之 间 expr 立 即 数 移 位 量, 值 为 1~31 条 件 码 标 志 : 指 令 会 更 新 N Z 和 C 标 志 ( 若 移 位 量 为 零, 则 不 影 响 C 标 志 ) LSL 指 令 举 例 如 下 LSL LSL R6,R7 R1,R6,#2 若 移 位 量 为 32, 则 Rd 清 零, 最 后 移 出 的 位 保 留 在 标 志 C 中 ; 若 移 位 量 大 于 32, 则 Rd 和 标 志 C 均 被 清 零 ; 若 移 位 量 为 0, 则 不 影 响 C 标 志 LSR 逻 辑 左 移 指 令. 数 据 逻 辑 左 移, 空 位 清 零, 移 位 结 果 保 存 到 Rd 中. 指 令 格 式 如 下 第 52 页
LSR LSR Rd,Rs Rd,Rm,#expr 其 中 Rd 目 标 寄 存 器, 也 是 第 一 个 操 作 数 寄 存 器. 必 须 在 R0~R7 之 间 Rs Rm 寄 存 器 控 制 移 位 中 包 含 移 位 量 的 寄 存 器. 必 须 在 R0~R7 之 间 立 即 数 移 位 的 源 寄 存 器. 必 须 在 R0~R7 之 间 expr 立 即 数 移 位 量, 值 为 1~32 条 件 码 标 志 : 指 令 会 更 新 N Z 和 C 标 志 ( 若 移 位 量 为 零, 则 不 影 响 C 标 志 ) LSR 指 令 举 例 如 下 LSR R3,R0 LSR R5,R2,#2 若 移 位 量 为 32, 则 Rd 清 零, 最 后 移 出 的 位 保 留 在 标 志 C 中 ; 若 移 位 量 大 于 32, 则 Rd 和 标 志 C 均 被 清 零, 若 移 位 量 为 0, 则 不 影 响 C 标 志. ROR 循 环 右 移 指 令. 数 据 循 环 右 移, 寄 存 器 右 边 移 出 的 位 循 环 移 回 到 左 边, 移 位 结 果 保 存 到 Rd 中, 指 令 格 式 如 下 ROR Rd,Rs 其 中 Rd 目 标 寄 存 器. 也 是 第 一 个 操 作 数 寄 存 器. 必 须 在 R0~R7 之 间 Rs 寄 存 器 控 制 移 位 中 包 含 移 位 量 的 寄 存 器. 必 须 在 R0~R7 之 间 条 件 标 志 : 指 令 会 更 新 N,Z,C 的 标 志 ( 若 移 位 量 为 零, 则 不 影 响 C 标 志 ). ROR 指 令 举 例 如 下 ROR R2,R3 比 较 指 令 CMP 比 较 指 令. 指 令 使 用 寄 存 器 Rn 的 值 减 去 第 二 个 操 作 数 的 值, 根 据 操 作 的 结 果 理 新 CPSR 中 的 相 应 条 件 标 志 位. 指 令 格 式 如 下 CMP Rn,Rm CMP Rn,#expr 第 53 页
其 中 Rn 第 一 个 操 作 数 寄 存 器. 对 CMP,Rn#expr 指 令,Rn 在 R0~R7 之 间 ; 对 于 CMP,Rn,Rm 指 令 在 Rn 在 R0~R15 之 间 Rm 第 二 个 操 作 数 寄 存 器.Rm 在 R0~R15 之 间 expr 立 即 数, 值 为 0~255 条 件 码 标 志 : 指 令 会 更 新 N Z C 和 V 标 志 CMP 指 令 举 例 如 下 CMP R1,#10 CMP R1,R2 ;R1 与 10 比 较, 设 置 相 关 标 志 位 ;R1 与 R2 比 较, 设 置 相 关 标 志 位 CMN 负 数 比 较 指 令. 指 令 使 用 寄 存 器 Rn 的 值 加 上 寄 存 器 Rm 的 值, 根 据 操 作 的 结 果 理 新 CPSR 中 的 相 应 条 件 标 志. 位 指 令 格 式 如 下 CMN Rn,Rm 其 中 Rn 第 一 个 操 作 数 寄 存 器, 必 须 在 R0~R7 之 间 Rm 第 二 个 操 作 数 寄 存 器. 必 须 在 R0~R7 之 间 条 件 码 标 志 : 指 令 会 更 新 N Z C 和 V 标 志. CMN 指 令 举 例 如 下 CMM R0,R2 ;R0 与 R2 进 行 比 较 TST 位 测 试 指 令. 指 令 将 寄 存 器 Rn 的 值 与 寄 存 器 Rm 的 值 按 位 作 逻 辑 与 操 作. 根 据 操 作 的 结 果 理 新 CPSR 相 应 条 件 标 志 位. 指 令 格 式 如 下. TST Rn,Rm 其 中 Rn 第 一 个 操 作 数 寄 存 器. 必 须 在 R0~R7 之 间 Rm 第 二 个 操 作 数 寄 存 器. 必 须 在 R0~R7 之 间 条 件 码 标 志 : 指 令 会 更 新 N Z C 和 V 标 志 TST 指 令 举 例 如 下 MOV R0,#x01 TST R1,R0, ; 判 断 R1 的 最 低 位 是 否 为 0 第 54 页
Thumb 跳 转 指 令 助 记 符 说 明 操 作 条 件 码 位 置 B label 跳 转 指 令 PC label B{cond} BL label 带 链 接 的 跳 转 指 令 LR PC 4,PC label 无 BX Rm 带 状 态 切 换 的 跳 转 指 令 PC label 切 换 处 理 器 状 态 无 B 跳 转 指 令. 跳 转 到 指 定 的 地 址 执 行 程 序. 这 是 Thumb 指 令 集 中 的 惟 一 的 有 条 件 执 行 指 令. 指 令 格 式 如 下 B{cond} label 跳 转 指 令 B 举 例 如 下 B BEQ WAITB LOOP1 若 使 用 cond 则 label 必 须 在 当 前 指 令 的 -252~+256 字 节 范 围 内 ; 若 指 令 是 无 条 件 的, 则 跳 转 指 令 label 必 须 在 当 前 指 令 的 ±2K 字 节 范 围 内 BL 带 链 接 的 跳 转 指 令. 指 令 先 将 下 一 条 指 令 的 地 址 拷 贝 到 R14( 即 LR) 链 接 寄 存 器 中, 然 后 跳 转 到 指 定 地 址 运 行 程 序. 指 令 格 式 如 下 : BL label 带 链 接 的 跳 转 指 令 BL 举 例 如 下 BL DELAYI 机 器 级 转 指 令 BL 限 制 在 当 前 指 令 的 ±4Mb 的 范 围 内.( 必 要 时,ARM 链 接 器 插 入 代 码 以 允 许 更 长 的 转 移.) BX 带 状 态 切 换 的 跳 转 指 令. 跳 转 到 Rm 指 定 的 地 址 执 行 程 序. 若 Rm 的 位 [0] 为 0, 则 Rm 的 位 于 也 必 须 为 0, 跳 转 时 自 动 将 CPSR 中 的 标 志 T 复 位, 即 把 目 标 地 址 的 代 码 解 释 为 ARM 代 码. 指 令 格 式 BX Rm 带 状 态 切 换 的 跳 转 指 令 BX 举 例 如 下. 第 55 页
ADR R0,ArmFun BX R0 ; 跳 转 到 R0 指 定 的 地 址, 并 根 据 R0 的 最 低 位 来 切 换 处 理 器 状 态. Thumb 杂 项 指 令 SWI 软 中 断 指 令.SWI 指 令 用 于 产 生 软 中 断, 从 而 实 现 在 用 户 模 式 变 换 到 管 理 模 式.CPSR 保 存 到 管 理 模 式 的 SPSR 中, 执 行 转 移 到 SWI 向 量. 在 其 它 模 式 下 也 可 使 用 SWI 指 令, 处 理 器 同 样 地 切 换 到 管 理 模 式. 指 令 格 式 如 下. SWI immed_8 其 中 immed_8 8 位 立 即 数, 值 为 0~255 之 间 的 整 数. SWI 指 令 举 例 如 下 SWI 1 ; 软 中 断, 中 断 立 即 数 为 0 SWI 0x55 ; 软 中 断, 中 断 立 即 数 为 0x55 使 用 SWI 指 令 时, 通 常 使 用 以 下 两 种 方 法 进 行 传 递 参 数,SWI 异 常 中 断 处 理 程 序 可 以 提 供 相 关 的 服 务, 这 两 种 方 法 均 是 用 户 软 件 协 定.SWI 异 常 中 断 处 理 程 序 要 通 过 读 取 引 起 软 中 断 的 SWI 指 令. 以 取 得 8 位 立 即 数. 1. 指 令 中 8 位 的 立 即 数 指 定 了 用 户 请 求 的 服 务 类 型, 参 数 通 过 用 寄 存 器 传 递. MOV R0,#34 ; 设 置 子 功 能 号 为 虎 作 34 SWI 18 ; 调 用 18 号 软 中 断 2. 指 令 中 的 8 位 立 即 数 被 忽 略, 用 户 请 求 的 服 务 类 型 由 寄 存 器 R0 的 值 决 定, 参 数 通 过 其 它 的 通 用 寄 存 器 传 递. MOV R0,#18 ; 调 用 18 号 软 中 断 MOV R1,#34 ; 设 置 子 功 能 号 为 了 4 SWI 0 第 56 页
Thumb 伪 指 令 ADR 小 范 围 的 地 址 读 取 伪 指 令.ADR 指 令 将 基 于 PC 相 对 偏 移 的 地 址 值 读 取 到 寄 存 器 中.ADR 伪 指 令 格 式 如 下. ADR register,expr 其 中 register 加 载 的 目 标 寄 存 器. expr 地 址 表 达 式. 偏 移 量 必 须 是 正 数 并 小 于 1KB.Expr 必 须 局 部 定 义, 不 能 被 导 入. ADR 伪 指 令 举 例 如 下 ADR register, expr 其 中 register 加 载 的 目 标 寄 存 器 expr 地 址 表 达 式 偏 移 量 必 须 是 正 数 并 小 说 于 1KB Expr 必 须 局 部 ADR 伪 指 令 举 例 如 下 : 定 义, 不 能 被 导 入 ADR R0,TxtTab TxtTab DCB ARM7TDMI,0 LDR 大 范 围 的 地 址 读 取 伪 指 令.LDR 伪 指 令 用 于 加 载 32 位 的 立 即 数 或 一 个 地 址 值 到 指 定 寄 存 器. 在 汇 编 编 译 源 程 序 时,LDR 伪 指 令 被 编 译 器 替 换 成 一 条 合 适 的 指 令. 若 加 载 的 常 数 未 超 出 MOV 范 围, 则 使 用 MOV 或 MVN 指 令 代 替 LDR 伪 指 令, 否 则 汇 编 器 将 常 量 放 入 文 字 池, 并 使 用 一 条 程 序 相 对 偏 移 的 LDR 指 令 从 文 字 池 读 出 常 量.LDR 伪 指 令 格 式 如 下. LDR register,=expr/label_expr 其 中, register 加 载 的 目 标 寄 存 器 expr 32 位 立 即 数. label_expr 基 于 PC 的 地 址 表 达 式 或 外 部 表 达 式. LADR 伪 指 令 举 例 如 下 ; 第 57 页
LDR R0,=0x12345678 ; 加 载 32 位 立 即 数 0x12345678 LDR R0,=DATA_BUF+60 ; 加 载 DATA_BUF 地 址 +60 LTORG ; 声 明 文 字 池 从 PC 到 文 字 池 的 偏 移 量 必 须 是 正 数 小 于 是 1KB. 与 Thumb 指 令 的 LDR 相 比, 伪 指 令 的 LDR 的 参 数 有 = 号. NOP 空 操 作 伪 指 令.NOP 伪 指 令 在 汇 编 时 将 会 将 会 被 代 替 成 ARM 中 的 空 操 作, 比 如 可 能 为 MOV,R8,R8 指 令 等.NOP 伪 指 令 格 式 如 下. NOP NOP 可 用 于 延 进 操 作 第 58 页
伪 指 令 ARM 汇 编 程 序 的 由 机 器 指 令, 伪 指 令 和 宏 指 令 组 成. 伪 指 令 不 像 机 器 指 令 那 样 在 处 理 器 运 行 期 间 由 机 器 执 行, 而 是 汇 编 程 序 对 源 程 序 汇 编 期 间 由 汇 编 程 序 处 理. 在 前 面 的 指 令 集 章 节 中, 我 们 已 经 接 触 了 几 条 常 用 到 的 伪 指 令, 如 ADR,ADRL,LDR,NOP 等, 把 它 们 和 指 令 集 一 起 介 绍 是 因 为 它 们 在 汇 编 时 会 被 合 适 的 机 器 指 令 代 替, 实 现 真 正 机 器 指 令 操 作. 宏 是 一 段 独 立 的 程 序 代 码, 它 是 通 过 伪 指 令 定 义 的, 在 程 序 中 使 用 宏 指 令 即 可 调 用 宏. 当 程 序 被 汇 编 时, 汇 编 程 序 将 对 每 个 调 用 进 行 展 开, 用 宏 定 义 取 代 源 程 序 中 的 宏 指 令. 符 号 定 义 伪 指 令 符 号 定 义 伪 指 令 用 于 定 义 ARM 汇 编 程 序 的 变 量, 对 变 量 进 行 赋 值 以 及 定 义 寄 存 器 名 称, 该 类 伪 指 令 如 下 ; 全 局 变 量 声 明 :GBLA,GBLL 和 GBLS 局 部 变 量 声 明 :LCLA,LCLL 和 LCLS 变 量 赋 值 : SETA,SETL 和 SETS 为 一 个 通 用 寄 存 器 列 表 定 义 名 称 :RLIST 为 一 个 协 处 理 器 的 寄 存 器 定 义 名 称 :CN 为 一 个 协 处 理 定 义 名 称 : CP 为 一 个 VFP 寄 存 器 定 义 名 称 :DN 和 SN 为 一 个 FPA 浮 点 寄 存 器 定 义 名 称 :FN GBLA GBLL GBLS 全 局 变 量 声 明 伪 指 令. GBLA 伪 指 令 用 于 声 明 一 个 全 局 的 算 术 变 量, 并 将 其 初 始 化 为 0; GBLL 伪 指 令 用 于 声 明 一 个 全 局 的 逻 辑 变 量, 并 将 其 初 始 化 为 {FALSE}; GBLS 伪 指 令 用 于 声 明 一 个 全 局 的 字 符 串 变 量, 并 将 其 初 始 化 为 空 字 符 串 伪 指 令 格 式 ; GBLA variable 第 59 页
GBLL GBLS 其 中 variable variable variable 定 义 的 全 局 变 量 名, 在 其 作 用 范 围 内 必 须 惟 一. 全 局 变 量 的 作 用 范 围 为 包 含 该 变 量 的 源 程 序. 伪 指 令 应 用 举 例 如 下 ; GBLL codedbg ; 声 明 一 个 全 局 逻 辑 变 量 codebg SETL {TRUE} ; 设 置 变 量 为 {TRUE} LCLA LCLL LCLS 局 部 变 量 声 明 伪 指 令. 用 于 宏 定 义 的 体 中. LCLA 伪 指 令 用 于 声 明 一 个 局 部 的 算 术 变 量, 并 将 其 初 始 化 为 0 LCLL 伪 指 令 用 于 声 明 一 个 局 部 的 逻 辑 变 量, 并 将 其 初 始 化 为 {FALSE} LCLS 伪 指 令 用 于 声 明 一 个 局 部 的 字 符 串 变 量, 并 将 其 初 始 化 为 空 字 符 串 伪 指 令 格 式 ; LCLA LCLL LCLS 其 中 variable variable variable variable 定 义 的 局 部 变 量 名 在 其 作 用 范 围 内 必 须 惟 一 局 部 变 量 的 作 用 范 围 为 包 含 该 局 部 变 量 只 能 在 宏 中 进 行 声 明 及 使 用 伪 指 令 应 用 举 例 如 下 ; MACRO SENDDAT $dat ; 声 明 一 个 宏 ; 宏 的 原 型 LCLA bitno ; 声 明 一 个 局 部 算 术 变 量 bitno SETA 8 ; 设 置 变 量 值 为 8 MEND 第 60 页
SETA SETL SETS 变 量 赋 值 伪 指 令. 用 于 对 已 定 义 的 全 局 变 量, 局 部 变 量 赋 值. SETA 伪 指 令 用 于 给 一 个 全 局 / 局 部 的 算 术 变 量 赋 值. SETL 伪 指 令 用 于 给 一 个 全 局 / 局 部 的 逻 辑 变 量 赋 值. SETS 伪 指 令 用 于 给 一 个 全 局 / 局 部 的 字 符 串 变 量 赋 值. 伪 指 令 格 式 ; variable_a SETA expr_a variable_l SETL expr_l variable_s SETS expr_s 其 中 variable_a 算 术 变 量. 用 GBLA,LCLA 伪 指 令 定 义 的 变 量. expr_a 赋 值 的 常 数. variable_l 逻 辑 变 量. 用 GBLL,LCLL 伪 指 令 定 义 的 变 量. expr_l 逻 辑 值, 即 {TRUE} 或 {FALSE}. variable_s 字 符 串 变 量. 用 GBLS,LCLS 伪 指 令 定 义 的 变 量. expr_s 赋 值 的 字 符 串. 伪 指 令 应 用 举 例 如 下. GBLS ErrStr ErrStr SETS No,semaphone RLIST RLIST 为 一 个 通 用 寄 存 器 列 表 定 义 名 称. 伪 指 令 格 式 如 下 : name RLIST {reglist} 其 中 name 要 定 义 的 寄 存 器 列 表 的 名 称. reglist 通 用 寄 存 器 列 表. 伪 指 令 应 用 举 例 如 下 ; LoReg RLIST {R0-R7} ; 定 义 寄 存 器 列 表 LoReg 第 61 页
STMFD SP!,LoReg ; 保 存 寄 存 器 列 表 LoReg CN CN 为 一 个 协 处 理 器 的 寄 存 器 定 义 名 称. 伪 指 令 格 式 ; name CN expr 其 中 name 要 定 义 的 协 处 理 器 的 寄 存 器 名 称. expr 协 处 理 器 的 寄 存 器 编 号, 数 值 范 围 为 0~15. 伪 指 令 应 用 举 例 如 下 ; MemSet CN l ; 将 协 处 理 的 寄 存 器 l 名 称 定 义 为 MemSet CP CP 为 一 个 协 处 理 器 定 义 的 名 称. 伪 指 令 格 式 ; name CP expr 其 中 name 要 定 义 的 协 处 理 器 名 称. expr 协 处 理 器 的 编 号, 数 值 范 围 为 0~15. 伪 指 令 应 用 举 例 如 下 ; DivRun CN 5 ; 将 协 处 理 器 5 名 称 定 义 为 DivRun DN SN DN 和 SN 为 VFP 的 寄 存 器 的 名 称 定 义 的 伪 指 令. DN 为 一 个 双 精 度 原 VFP 寄 存 器 定 义 名 称. SN 为 一 个 单 精 度 的 VFP 寄 存 器 定 义 名 称. 伪 指 令 格 式 ; name DN expr 第 62 页
name SN expr 其 中 name 要 定 义 的 VFP 寄 存 器 名 称. expr 双 精 度 的 VFP 寄 存 器 编 号 为 0~15, 单 精 度 的 VFP 寄 存 器 编 号 为 0~31. 伪 指 令 应 用 举 例 如 下 ; cdn DN 1 rex SN 3 ; 将 VFP 双 精 度 寄 存 器 1 名 称 定 义 为 cdn ; 将 VFP 单 精 度 寄 存 器 3 名 称 定 义 为 rex FN FN 为 一 个 FPA 浮 点 寄 存 器 定 义 名 称 伪 指 令 格 式 ; name FN expr 其 中 name 要 定 义 的 浮 点 寄 存 器 名 称. expr 浮 点 寄 存 器 的 编 号, 值 为 0~7 伪 指 令 应 用 举 例 如 下 ; ibq FN l ; 将 浮 点 寄 存 器 l 名 称 定 义 为 ibq 数 据 定 义 伪 指 令 数 据 定 义 伪 指 令 用 于 数 据 表 定 义, 文 字 池 定 义, 数 据 空 间 分 配 等. 该 类 伪 指 令 如 下 ; 声 明 一 个 文 字 池 :LTORG; 定 义 一 个 结 构 化 的 内 存 表 的 首 地 址 :MAP 定 义 结 构 化 内 存 表 中 的 一 个 数 据 域 :FIELD 分 配 一 块 内 存 空 间, 并 用 0 初 始 化 :SPACE 分 配 一 段 字 节 的 内 存 单 元, 并 用 指 定 的 数 据 初 始 化 :DCB; 分 配 一 段 字 的 内 存 单 元, 并 用 指 令 的 数 据 初 始 化 :DCD 和 DCDU; 分 配 一 段 字 的 内 存 单 元, 将 每 个 单 元 的 内 容 初 始 化 为 该 单 元 相 对 于 静 态 基 址 寄 存 器 的 偏 移 量 :DCDO; 分 配 一 段 双 字 的 内 存 单 元, 并 用 双 精 度 的 浮 点 数 据 初 始 化 :DCFD 和 DCFDU; 分 配 一 段 字 的 内 存 单 元, 并 用 单 精 度 的 浮 点 数 据 初 始 化 :DCFS 和 DCFSU; 第 63 页
分 配 一 段 字 的 内 存 单 元, 并 用 单 精 度 的 浮 点 数 据 初 始 化, 指 定 内 存 单 元 存 放 的 是 代 码, 而 不 是 数 据 :DCI 分 配 一 段 双 字 的 内 存 单 元, 并 用 64 位 整 数 数 据 初 始 化 :DCQ 和 DCQU 分 配 一 段 半 字 的 内 存 单 元, 并 用 指 定 的 数 据 初 始 化 :DCW 和 DCWU; LTORG LTORG 用 于 声 明 一 个 文 字 池, 在 使 用 LDR 伪 指 令 时, 要 在 适 当 的 地 址 加 入 LTORG 声 明 文 字 池, 这 样 就 会 把 要 加 载 的 数 据 保 存 在 文 字 池 内, 再 用 ARM 的 加 载 指 令 读 出 数 据.( 若 没 有 使 用 LTORG 声 明 文 字 池, 则 汇 编 器 会 在 程 序 末 尾 自 动 声 明.) 伪 指 令 格 式 : LTORG 伪 指 令 应 用 举 例 如 下 ; LDR ADD MOV R0,=0x12345678 R1,R1,R0 PC,LR LTORG ; 声 明 文 字 池, 此 地 址 存 储 0x12345678 ; 其 它 代 码 LTORG 伪 指 令 常 放 在 无 条 件 跳 转 指 令 之 后, 或 者 子 程 序 返 回 指 令 之 后, 这 样 处 理 器 就 不 会 错 误 地 将 文 字 池 中 的 数 据 当 作 指 令 来 执 行. MAP MAP 用 于 定 义 一 个 结 构 化 的 内 存 表 的 首 地 址. 此 时, 内 存 表 的 位 置 计 数 器 {VAR} 设 置 为 该 地 址 值 {VAR} 为 汇 编 器 的 内 置 变 量.^ 与 MAP 同 义. 伪 指 令 格 式 : MAP expr,{base_register} 其 中 expr 数 字 表 达 式 或 程 序 中 的 标 号. 当 指 令 中 没 有 base_register 时,expr 即 为 结 构 化 内 存 表 的 首 地 址. 第 64 页
base_register 一 个 寄 存 器. 当 指 令 中 包 含 这 一 项 时, 结 构 化 内 存 表 的 首 地 伪 指 令 应 用 举 例 如 下 ; 址 为 expr 与 base_register 寄 存 器 值 的 和. MAP 0x00,R9 ; 定 义 内 存 表 的 首 地 址 为 R9 Timer FIELD 4 ; 定 义 数 据 域 Timer, 长 度 为 4 字 节 Attrib FIELD 4 ; 定 义 数 据 域 Attrib, 长 度 为 4 字 节 String FIELD 100 ; 定 义 数 据 域 String, 长 度 为 100 字 节 ADR R9,DataStart ; 设 置 R9 的 值, 即 设 置 结 构 化 的 内 存 表 地 址 LDR R0,Atrrib ; 相 当 于 LDR,R0,[R9,#4] MAP 伪 指 令 和 FIELD 伪 指 令 配 合 使 用, 用 于 定 义 结 构 化 的 内 存 表 结 构.MAP 伪 指 令 中 的 base-register 寄 存 器 的 值 对 于 其 后 所 有 的 FIELD 伪 指 令 定 义 的 数 据 域 是 默 认 使 用 的, 直 到 遇 到 新 的 包 含 base-register 项 的 MAP 伪 指 令. FIELD FIELD 用 于 定 义 一 个 结 构 化 内 存 表 中 的 数 据 域.# 与 FIELD 同 义. 伪 指 令 格 式 : {tabel} FIELD expr 其 中 label 当 指 令 中 包 含 这 一 项 时,label 的 值 为 当 前 内 存 表 的 位 置 计 数 伪 指 令 应 用 举 例 如 下 ; 器 {VAR} 的 值, 汇 编 编 译 器 处 理 了 这 条 FIELD 伪 指 令 后, 内 存 表 计 数 器 的 值 将 加 上 expr. expr 表 示 本 数 据 域 在 内 存 表 中 所 占 用 的 字 节 数. MAP 0x40003000 ; 内 存 表 的 首 地 址 为 0x40003000 count1 FIELD 4 ; 定 义 数 据 域 count1, 长 度 为 4 字 节 count2 FIELD 4 ; 定 义 数 据 域 count2, 长 度 为 4 字 节 count3 FIELD 4 ; 定 义 数 据 域 count3, 长 度 为 4 字 节 第 65 页
LDR R1,count1 ;R1=[0x40003000+0x00] STR R1,count2 ;[0x40003000+0x00]=R1 MAP,FIELD 伪 指 令 仅 仅 是 定 义 数 据 结 构, 它 们 并 不 实 际 分 配 内 存 单 元. SPACE SPACE 用 于 分 配 一 块 内 存 单 元, 并 用 0 初 始 化.% 与 SPACE 同 义. 伪 指 令 格 式 : {label} SPACE expr 其 中 label 内 存 块 起 始 地 址 标 号. expr 所 要 分 配 的 内 存 字 节 数. 伪 指 令 应 用 举 例 如 下 ; AREA DataRA,DATA,READWROTE ; 声 明 一 数 据 段, 名 为 DataRAM DataBuf SPACE 1000 ; 分 配 1000 字 节 空 间 DCB DCB 用 于 分 配 一 段 字 节 内 存 单 元, 并 用 伪 指 令 中 的 expr 初 始 化. 一 般 可 用 来 定 义 数 据 表 格, 或 文 字 符 串.= 与 DCB 同 义. 伪 指 令 格 式 : {label} DCB expr{,expr}{,expr} 其 中 label 内 存 块 起 始 地 址 标 号. expr 可 以 为 -128~255 的 数 值 或 字 符 串. 内 存 分 配 的 字 节 数 由 expr 个 数 决 定. 伪 指 令 应 用 举 例 如 下 DISPTAB DCB 0x33,0x43,0x76,0x12 DCB -120,20,36,55 ERRSTR DCB Send,data is error!,0 第 66 页
DCD 和 DCDU DCD 用 于 分 配 一 段 字 内 存 单 元, 并 用 伪 指 令 中 的 expr 初 始 化.DCD 伪 指 令 分 配 的 内 存 需 要 字 对 齐, 一 般 可 用 来 定 义 数 据 表 格 或 其 它 常 数.& 与 DCD 同 义. DCDU 用 于 分 配 一 段 字 内 存 单 元, 并 用 伪 指 令 中 的 expr 初 始 化.DCD 伪 指 令 分 配 的 内 存 不 需 要 字 对 齐, 一 般 可 用 来 定 义 数 据 表 格 或 其 它 常 数. 伪 指 令 格 式 : {label} DCD expr{,expr}{,expr} {label} DCDU expr{,expr}{,expr} 其 中 label 内 存 块 起 始 地 址 标 号. expr 常 数 表 达 式 或 程 序 中 的 标 号. 内 存 分 配 字 节 数 由 expr 个 数 决 定. 伪 指 令 应 用 举 例 如 下 : Vectors LDR LDR PC,ReserAddr PC,UndefinedAddr ResetAddr DCD Reset UndefinedAddr DCD Undefined Reset Undefined DCDO DCDO 用 于 分 配 一 段 字 内 存 单 元. 并 将 每 个 单 元 的 内 容 初 始 化 为 该 单 元 相 对 于 静 态 基 址 寄 存 器 的 偏 移 量.DCDO 伪 指 令 作 为 基 于 静 态 基 址 寄 存 器 R9 的 偏 移 量 分 配 内 存 单 元.DCDO 伪 指 令 分 配 的 内 存 需 要 字 对 齐. 伪 指 令 格 式 ; 第 67 页
{label} DCDO expr{,expr}{,expr} 其 中 label 内 存 块 起 始 地 址 标 号. expr 地 址 偏 移 表 达 式 或 程 序 中 的 标 号. 内 存 分 配 的 字 数 由 expr 个 数 决 定. 伪 指 令 应 用 举 例 如 下 ; IMPORT externsym DCDO externsym ; 分 配 32 位 的 字 单 元, 其 值 为 标 号 externsym 基 于 R9 的 偏 移 DCFD 和 DCFDU DCFD 用 于 分 配 一 段 双 字 的 内 存 单 元, 并 用 双 精 度 的 浮 点 数 据 fpliteral 初 始 化 每 个 双 精 度 的 浮 点 数 占 据 两 个 字 单 元 DCFD 伪 指 令 分 配 的 内 存 需 要 字 对 齐 DCFDU 具 有 DCFD 同 样 的 功 能, 但 分 配 的 内 存 不 需 要 字 对 齐 伪 指 令 格 式 : {label} DCFD fpliteral{,fpliteral}{,fpliteral} {label} DCFDU fpliteral{,fpliteral}{,fpliteral} 其 中 label 内 存 块 起 始 地 址 标 号. fpliteral 双 精 度 的 浮 点 数. 伪 指 令 应 用 举 例 如 下 ; DCFD 2E30,-3E-20 DCFDU -.1,1000,2.1E18 DCFS 和 DCFSU DCFS 用 于 分 配 一 段 字 的 内 存 单 元, 并 用 单 精 度 的 浮 点 数 据 fpliteral 初 始 化. 每 个 单 精 度 的 浮 点 数 占 据 一 个 字 单 元.DCFD 伪 指 令 分 配 的 内 存 需 要 字 对 齐. DCFSU 具 有 DCFS 同 样 的 功 能, 但 分 配 的 内 存 不 需 要 字 对 齐. 伪 指 令 格 式 : {label} DCFS fpliteral{,fpliteral}{,fpliteral} {label} DCFSU fpliteral{,fpliteral}{,fpliteral} 其 中 label 内 存 块 起 始 地 址 标 号 第 68 页
fpliteral 单 精 度 的 浮 点 数. 伪 指 令 应 用 举 例 如 下 ; DCFS 1.1E2,-1.3E10,0.0999 DCI 在 ARM 代 码 中,DCI 用 于 分 配 一 段 字 节 的 内 存 单 元, 用 指 定 的 数 据 expr 初 始 化. 指 定 内 存 单 元 存 放 的 是 代 码, 而 不 是 数 据. 在 Thumb 代 码 中,DCI 用 于 分 配 一 段 半 字 节 的 内 存 单 元, 用 指 定 的 数 据 expr 初 始 化. 指 定 内 存 单 元 存 放 的 是 代 码, 而 不 是 数 据. 伪 指 令 格 式 : {label} DCI expr 其 中 label 内 存 块 起 始 地 址 标 号. expr 可 为 数 字 表 达 式. DCI 伪 指 令 和 DCD 伪 指 令 非 常 类 似, 不 同 之 处 在 于 DCI 分 配 的 内 存 中 的 数 据 被 标 识 为 指 令. 可 用 于 通 过 宏 指 令 业 定 义 处 理 器 不 支 持 的 指 令. 伪 指 令 应 用 举 例 如 下 ; MACRO ; 宏 定 义 ( 定 义 NEWCMN Rd,Rn 指 令 ) NEWCMN $Rd,$Rm ; 宏 名 为 NEWCMN, 参 数 为 Rd 和 Rm DCI 0xe16a0e20:OR:($Rd:SHL:12):OR:$Rm MEND DCQ 和 DCQU DCQ 用 于 分 配 一 段 双 字 的 内 存 单 元, 并 用 64 位 的 整 数 数 据 literal 初 始 化.DCQ 伪 指 令 分 配 的 内 存 需 要 字 对 齐. DCQU 具 有 DCQ 同 样 的 功 能, 但 分 配 的 内 存 不 需 要 字 对 齐. 伪 指 令 格 式 : {label} DCQ {-}literal{,{-}{literal}} {label} DCQU {-}literal{,{-}{literal}} 第 69 页
其 中 label 内 存 块 起 始 地 址 标 号. literal 64 位 的 数 字 表 达 式. 取 值 范 围 为 0~2 64-1 当 literal 前 有. 号 时, 取 值 范 围 为 -2 63 ~-1 之 间 伪 指 令 应 用 举 例 如 下 ; DCQU 1234,-76568798776 DCW 和 DCWU DCW 用 于 分 配 一 段 字 的 内 存 单 元, 并 用 指 定 的 数 据 expr 初 始 化.DCW 伪 指 令 分 配 的 内 存 需 要 字 对 齐. DCWU 具 有 DCW 同 样 的 功 能, 但 分 配 的 内 存 不 需 要 字 对 齐. 伪 指 令 格 式 : {label} DCW expr{,expr}{,expr} {label} DCWU expr{,expr}{,expr} 其 中 label 内 存 块 起 始 地 址 标 号. expr 数 字 表 达 式, 取 值 范 围 为 -32768~65535. 伪 指 令 应 用 举 例 如 下 ; DCW -592,123,6756 报 告 伪 指 令 报 告 伪 指 令 用 于 汇 编 报 告 指 示. 该 类 伪 指 令 如 下 : 断 言 错 误 :ASSERT; 汇 编 诊 断 信 息 显 示 :INFO; 设 置 列 表 选 项 :OPT; 插 入 标 题 :TTL 和 SUBT. ASSERT ASSERT 为 断 言 错 误 伪 指 令. 在 汇 编 编 译 器 对 汇 编 程 序 的 第 二 遍 扫 描 中, 如 果 其 中 ASSERT 条 件 不 成 立,ASSERT 伪 指 令 将 报 告 该 错 误 信 息. 第 70 页
伪 指 令 格 式 : ASSERT Logical_expr 其 中 Logical_expr 用 于 断 言 的 逻 辑 表 达 式 伪 指 令 应 用 举 例 如 下 ASSERT Top<>Temp ; 断 言 Top 不 等 于 Temp INFO 汇 编 诊 断 信 息 显 示 伪 指 令, 在 汇 编 器 处 理 过 程 中 的 第 一 遍 扫 描 或 第 一 遍 扫 描 时 报 告 诊 断 信 息. 伪 指 令 格 式 : INFO numeric_expr,string_expr 其 中 numeric_expr 数 据 表 达 式. 若 值 为 0, 则 在 第 一 遍 扫 描 时 报 告 诊 断 信 息. 否 则 在 第 一 遍 扫 描 时 报 告 诊 断 信 息. strint_expr 要 显 示 的 字 串 伪 指 令 应 用 举 例 如 下 : INFO 0, Version 0.1 ; 在 第 二 遍 扫 描 时, 报 告 版 本 信 息 if cont1 > cont2 ; 如 果 cont1 > cont2 INFO 1, cont1 > cont2 ; 则 在 第 一 遍 扫 描 时 报 告 cont1 > cont2 OPT 设 置 列 表 选 项 伪 指 令. 通 过 OPT 伪 指 令 可 以 在 源 程 序 中 设 置 列 表 选 项. 伪 指 令 格 式 : OPI n 其 中 n 所 设 置 的 选 项 的 编 码 如 下 : 1 设 置 常 规 列 表 选 项 2 关 闭 常 规 列 表 选 项 4 设 置 分 页 符, 在 新 的 一 页 开 始 显 示 8 将 行 号 重 新 设 置 为 0 第 71 页
16 设 置 选 项, 显 示 SET,GBL,LCL 伪 指 令 32 设 置 选 项, 不 显 示 SET,GBL,LCL 伪 指 令 64 设 置 选 项, 显 示 宏 展 开 128 设 置 选 项, 不 显 示 宏 展 开 256 设 置 选 顶, 显 示 宏 调 用 512 设 置 先 项, 不 显 示 宏 调 用 1024 设 置 选 顶, 显 示 第 一 遍 扫 描 列 表 2048 设 置 选 项, 不 显 示 第 一 遍 扫 描 列 表 4096 设 置 选 项 目, 显 示 条 件 汇 编 伪 指 令 8192 设 置 选 项, 不 显 示 条 件 汇 编 伪 指 令 16384 设 置 选 项, 显 示 MEND 伪 指 令 32768 设 置 选 项, 不 显 示 MEND 伪 默 认 情 况 下,-list 选 项 生 成 常 规 的 列 表 文 件, 包 括 变 量 声 明, 宏 展 开, 条 件 汇 编 伪 指 令 及 MEND 伪 指 令, 而 且 列 表 文 件 只 是 在 第 二 遍 扫 描 时 给 出, 通 过 OPT 伪 指 令, 可 以 在 源 程 序 中 改 变 默 认 的 选 项. 伪 指 令 应 用 举 例 如 下 ; 代 码 OPT 512 ; 不 显 示 宏 调 用 ; 代 码 TTL 和 SUBT TTL 和 SUBT 为 插 入 标 题 伪 指 令. TTL 伪 指 令 在 列 表 文 件 的 每 一 页 的 开 头 插 入 一 个 标 题. 该 TTL 伪 指 令 的 作 用 在 其 后 的 每 一 页, 直 到 遇 到 新 的 TTL 伪 指 令. SUBT 伪 指 令 在 列 表 文 件 的 每 页 的 开 头 第 一 个 子 标 题. 该 SUBT 伪 指 令 的 作 用 在 其 后 的 每 一 页, 直 到 遇 到 新 的 SUBT 伪 指 令. 伪 指 令 格 式 : TTL title SUBT subtitle 第 72 页
其 中 title 标 题 名. subtitle 子 标 题 名. 伪 指 令 应 用 举 例 如 下 ; TTL mainc SUBT subc con 汇 编 控 制 伪 指 令 汇 编 控 制 伪 指 令 用 于 条 件 汇 编, 宏 定 义, 重 复 汇 编 控 制 等. 该 类 伪 指 令 如 下 : 条 件 汇 编 控 制 : IF,ELSE 和 ENDIF 宏 定 义 : MACRO 和 MEND 重 复 汇 编 : WHILE 及 WEND IF ELSE 和 ENDIF IF,ELSE 和 ENDIF 伪 指 令 能 够 根 据 条 件 把 一 段 代 码 包 括 在 汇 编 程 序 内 或 将 其 排 除 在 程 序 之 外. [ 与 IF 同 义, 与 ELSE 同 义,] 与 ENDIF 同 义 伪 指 令 格 式 : IF logical_expr ; 指 令 或 伪 指 令 代 码 段 1 { ELSE ; 指 令 或 伪 指 令 代 码 段 2 } 第 73 页
ENDIF 其 中 logical_expr 用 于 控 制 的 逻 辑 表 达 式. 若 条 件 成 立, 则 代 码 段 落 在 汇 编 源 程 序 中 有 效. 若 条 件 不 成 立, 代 码 段 1 无 效, 同 时 若 使 用 ELSE 伪 指 令, 代 码 段 有 效. 伪 指 令 应 用 举 例 如 下 ; IF {CONFIG}=16 BNE LDR BX rt_udiv_1 R0,= rt_div0 R0 ELSE BEQ rt_div0 ENDIF IF,ELSE 和 ENDIF 伪 指 令 是 可 以 嵌 套 使 用 的. MACRO 和 MEND MACRO 和 MEND 伪 指 令 用 于 宏 定 义.MACRO 标 识 宏 定 义 的 开 始,MEND 标 识 宏 定 义 久 的 结 束. 用 MACRO 及 MEND 定 义 的 一 段 代 码, 称 为 宏 定 义 体. 这 样 在 程 序 中 就 可 以 通 过 宏 指 令 多 次 调 用 该 代 码 段. 伪 指 令 格 式 : MACRO {$label} macroname {$parameter} {$parameter} MEND ; 宏 定 义 体. 其 中 $label 宏 指 令 被 展 开 时,label 可 被 替 换 成 相 应 的 符 号, 通 常 为 一 个 标 号 在 一 个 符 号 前 使 用 $ 表 示 被 汇 编 时 将 使 用 相 应 的 值 替 代 $ 后 的 符 号. macroname 所 定 义 的 宏 的 名 称. $parameter 宏 指 令 的 参 数. 当 宏 指 令 被 展 开 时 将 被 替 换 成 相 应 的 值, 类 第 74 页
似 于 函 数 中 的 形 式 参 数 对 于 子 程 序 代 码 比 较 短, 而 需 要 传 递 的 参 数 比 较 多 的 情 况 下 可 以 使 用 汇 编 技 术. 首 先 要 用 MACR 和 MEND 伪 指 令 定 义 宏, 包 括 宏 定 义 体 代 码. 在 MACRO 伪 指 令 之 后 的 第 一 行 声 明 宏 的 原 型, 其 中 包 含 该 宏 定 义 的 名 称, 及 需 要 的 参 数. 在 汇 编 程 序 中 可 以 通 过 该 宏 定 义 的 名 称 来 调 用 它. 当 源 程 序 被 汇 编 时, 汇 编 编 译 器 将 展 开 每 个 宏 调 用, 用 宏 定 义 体 代 替 源 程 序 中 的 宏 定 义 的 名 称, 并 用 实 际 的 参 数 值 代 替 宏 定 义 时 的 形 式 参 数. 伪 指 令 应 用 举 例 如 下 MACRO CSI_SETB ; 宏 名 为 CSI_SETB, 无 参 数 LDR R0,=rPDATG ; 读 取 GPG0 口 的 值 LDR R1,[R0] ORR R1,R1#0x01 ;CSI 置 位 操 作 STR R1,[R0] ; 输 出 控 制 MEND 带 参 数 的 宏 定 义 如 程 序 清 单 : MACRO $IRQ_Label HANDLER $IRQ_Exception EXPORT IMPORT $IRQ_Label $IRQ_Exception $IRQ_Label SUB STMFD MRS STMFD LR,LR,#4 SP!,{R0-R3,R12,LR} R3,STSR SP!,{R3} MEND WHIL 和 WEND WHILE 和 WEND 伪 指 令 用 于 根 据 条 件 重 复 汇 编 相 同 的 或 几 乎 相 同 的 一 段 源 程 序. 第 75 页
伪 指 令 格 式 : WHILE logical_expr ; 指 令 或 伪 指 令 代 码 段 WEND 其 中 logical_expr 用 于 控 制 的 逻 辑 表 达 式. 若 条 件 成 立, 则 代 码 段 在 汇 编 源 程 序 中 有 效, 并 不 断 重 复 这 段 代 码 直 到 条 件 不 成 立. 伪 指 令 应 用 举 例 如 下 ; WHILE no<5 no SETA no+1 WEND WHILE 和 WEND 伪 指 令 是 可 以 嵌 套 使 用 的. 杂 项 伪 指 令 杂 项 伪 指 令 在 汇 编 编 程 设 计 较 为 常 用, 如 段 定 义 伪 指 令, 入 口 点 设 置 伪 指 令, 包 含 文 件 伪 指 令, 标 号 导 出 或 引 入 声 明 等, 该 类 伪 指 令 如 下 ; 边 界 对 齐 : 段 定 义 : ALIGN AREA 指 令 集 定 义 : CODE16 和 CODE32 汇 编 结 束 : 程 序 入 口 : 常 量 定 义 : END ENTRY EQU 声 明 一 个 符 号 可 以 被 其 它 文 件 引 用 :EXPORT 和 GLORBAL 声 明 一 个 外 部 符 号 :IMPORT 和 EXTERN 包 含 文 件 :GET 和 INCLUDE 包 含 不 被 汇 编 的 文 件 :INCBIN 保 留 符 号 表 中 的 局 部 符 号 :KEEP 禁 止 浮 点 指 令 :NOFP 指 示 两 段 之 间 的 依 赖 关 系 :REQUIRE 第 76 页
堆 栈 8 字 节 对 准 :PEQUIRE8 和 PRESERVE8 给 特 定 的 寄 存 器 命 名 :RN 标 记 局 部 标 号 使 用 范 围 的 界 限 :ROUT. ALIGN ALIGN 伪 指 令 通 过 添 加 补 丁 字 节 使 当 前 位 置 满 足 一 定 的 对 齐 方 式. 伪 指 令 格 式 : ALIGN {expr{,offset}} 其 中 expr 数 字 表 达 式, 用 于 指 定 对 齐 的 方 式. 取 值 为 2 的 n 次 幂, 如 1,2,4,8, 等, 不 能 为 0 其 没 有 expr., 则 默 认 为 字 对 齐 方 式. offset 数 字 表 达 式, 当 前 位 置 对 齐 到 下 面 形 式 的 地 址 处 :offset+n*expr 在 下 面 的 情 况 中, 需 要 特 定 的 地 址 对 齐 方 式 ; 1.Thumb 伪 指 令 ADR 要 求 地 址 是 字 对 齐 的. 而 Thumb 代 码 中 地 址 标 号 可 能 不 是 字 对 齐 的. 这 时 就 要 使 用 伪 指 令 ALIGN4 使 Thumb 代 码 中 地 址 标 号 为 字 对 齐. 2. 由 于 有 些 ARM 处 理 器 的 Cache 采 用 了 其 他 对 齐 方 式. 如 16 字 节 对 齐 方 式, 这 时 使 用 ALIGN 伪 指 令 指 定 合 适 的 对 齐 方 式 可 以 充 分 发 挥 Cache 的 性 能 优 势. 3.LDRD 和 STRD 指 令 要 求 存 储 单 元 为 8 字 节 对 齐. 这 样 在 为 LDRD/STRD 指 令 分 配 的 存 储 单 元 前 要 使 用 伪 指 令 ALIGN8 实 现 8 字 节 对 齐 方 式. 4. 地 址 标 号 通 常 自 身 没 有 对 齐 要 求, 而 在 ARM 代 码 中 要 求 地 起 标 号 对 齐 是 字 对 齐 的,Thumb 代 码 中 要 求 半 字 对 齐. 这 样 可 以 使 用 ALIGN4 和 ALIGN2 伪 指 令 来 调 整 对 齐 方 式. 伪 指 令 应 用 举 例 如 下 : 通 过 ALIGN 伪 指 令 使 程 序 中 的 地 址 标 号 字 对 齐 : AREA Example,CODE,READONLY ; 声 明 代 码 段 Example START LDR R0,=Sdfjk MOV PC,LR Sdfjk DCB 0x58 ; 定 义 一 字 节 存 储 空 间, 字 对 齐 方 式 被 破 坏 ALIGN ; 声 明 字 对 齐 第 77 页
SUBI MOV R1,R3 ; 其 它 代 码 MOV PC,LR 在 段 定 义 AREA 中, 也 可 使 用 ALIGN 伪 指 令 对 齐, 但 表 达 式 的 数 字 含 义 是 同 的 AREA MyStack,DATA,NOINIT,ALIGN=2 ; 声 明 数 据 段 ;MyStack, 并 重 新 字 对 齐 IrqStackSpace SPACE IRQ_STACK_LEGTH*4 ; 中 断 模 式 堆 栈 空 间 FiqStackSpace SPACE FIQ_STACK_LEGTH*4 ; 快 速 中 断 模 式 堆 栈 空 间 AbtStackSpace SPACE ABT_STACK_LEGTH*4 ; 中 止 义 模 式 堆 栈 空 间 UndtStackSpace SPACE UND_STACK_LEGTH*4 ; 未 定 义 模 式 堆 栈 将 两 个 字 节 的 数 据 放 在 同 一 个 字 的 第 一 个 字 节 和 第 四 个 字 节 中, 带 offset 的 ALIGN 对 齐 : AREA offsetfxample, CODE DCB 0x31 ; 第 一 个 字 节 保 存 0x31 ALIGN 4,3 ; 字 对 齐 DCB 0x32 ; 第 四 个 字 节 保 存 0x32 AREA AREA 伪 指 令 用 于 定 义 一 个 代 码 段 或 数 据 段.ARM 汇 编 程 序 设 计 采 用 分 段 式 设 计, 一 个 ARM 源 程 序 至 少 需 要 一 个 代 码 段, 大 的 程 序 可 以 包 含 多 少 个 代 码 段 及 数 据 段. 伪 指 令 格 式 : AREA 其 中 sectionname{,attr}{,attr} sectionname 所 定 义 的 代 码 段 或 数 据 段 的 名 称. 如 果 该 名 称 是 以 数 据 开 头 的, 则 该 名 称 必 须 用 括 起 来, 如 1_datasec. 还 有 一 些 代 码 段 具 有 的 约 定 的 名 称. 如 text 表 示 C 语 言 编 译 器 产 生 的 代 码 段 或 者 与 C 语 言 库 相 关 的 代 码 段. attr 该 代 码 段 或 数 据 段 的 属 性. 第 78 页
在 AREA 伪 指 令 中, 各 属 性 之 间 用 逗 号 隔 开. 以 下 为 段 属 性 及 相 关 说 明 : ALIGN = expr. 默 认 的 情 况 下,ELF 的 代 码 段 和 数 据 段 是 4 字 节 对 齐 的,expr 可 以 取 0~31 的 数 值, 相 应 的 对 齐 方 为 2expr 字 节 对 齐. 如 expr=3 时 为 字 节 对 齐. 对 于 代 码 段,expr 不 能 为 0 或 1; ASSOC = section. 指 定 与 本 段 相 关 的 ELF 段. 任 何 时 候 连 接 section 段 也 必 须 包 括 sectionname 段 ; DODE 为 定 义 代 码 段. 默 认 属 性 为 READONLY; COMDEF 定 义 一 个 通 用 的 段. 该 段 可 以 包 含 代 码 或 者 数 据. 在 其 它 源 文 件 中, 同 名 的 COMDEF 段 必 须 相 同 ; COMMON 定 义 一 个 通 用 的 段. 该 段 不 包 含 任 何 用 户 代 码 和 数 据, 连 接 器 将 其 初 始 化 为 此. 各 源 文 件 中 同 名 的 COMMON 段 共 用 同 样 的 内 存 单 元, 连 接 器 为 其 分 配 合 适 的 尺 寸 ; DATA 为 定 义 段. 默 认 属 性 为 READWRITE; NOINIT 指 定 本 数 据 段 仅 仅 保 留 了 内 存 单 元, 而 没 有 将 各 初 始 写 入 内 存 单 元, 或 者 将 内 存 单 元 值 初 始 化 为 0; READONLY 指 定 本 段 为 只 读, 代 码 段 的 默 认 属 性 为 READONLY; READWRITE 指 定 本 段 为 可 读 可 写. 数 据 段 的 默 认 属 性 为 READWRITE; 使 用 AREA 伪 指 令 将 程 序 分 为 多 个 ELF 格 式 的 段, 段 名 称 可 以 相 同, 这 时 同 名 的 段 被 放 在 同 一 个 ELF 段 中. 伪 指 令 应 用 举 例 如 下 ; AREA Example,CODE,READNOLY ; 声 明 一 个 代 码, 名 为 Example CODE16 和 CODE32 CODE16 伪 指 令 指 示 汇 编 编 译 器 后 面 的 指 令 为 16 位 的 Thumb 指 令. CODE32 伪 指 令 指 示 汇 编 编 译 器 后 面 的 指 令 为 32 位 的 ARM 指 令. 伪 指 令 格 式 : CODE16 CODE32 CODE16 和 CODE32 伪 指 令 只 是 指 示 汇 编 编 译 器 后 面 的 指 令 的 类 型, 伪 指 令 本 身 并 不 进 行 程 序 状 态 的 切 换. 要 进 行 状 态 切 换, 可 以 使 用 BX 指 令 操 作. 第 79 页
伪 指 令 应 用 举 例 如 下 ; AREA Example CODE,READONLY CODE32 使 用 CODE16 和 CODE32 定 义 Thumb 指 令 及 ARM 指 令 并 用 BX 指 令 进 行 切 换 CODE16 和 CODE32 的 使 用 : AREA ArmThumC,CODE,READONLY CODE32 ADR BX R0,ThumbStart+1 R0 CODE16 ThumbStart MOV R0,#10 END END END 伪 指 令 用 于 指 示 汇 编 编 译 器 源 文 件 已 结 束. 每 一 个 汇 编 源 文 件 均 要 使 用 一 个 END 伪 指 令, 指 示 本 源 程 序 结 束 伪 指 令 格 式 : END ENTRY ENTRY 伪 指 令 用 于 指 定 程 序 的 入 口 点. 伪 指 令 格 式 : ENTRY 一 个 程 序 ( 可 以 包 含 多 个 源 文 件 ) 中 至 少 要 有 一 个 ENTRY, 可 以 有 多 个 ENTRY. 但 一 个 源 文 件 中 最 多 只 有 一 个 ENTRY. 第 80 页
伪 指 令 应 用 举 例 如 下. AREA, Example, CODE,READNOLY ENTRY CODE32 START MOV R1,#0x5F EQU EQU 伪 指 令 为 数 字 常 量, 基 于 寄 存 器 的 值 和 程 序 中 的 标 号 定 义 一 个 名 称 * 与 EQU 同 义 指 令 格 式 : name EQU expr{,type} 其 中 name 要 定 义 的 常 量 的 名 称. expr 基 于 寄 存 器 的 地 址 值, 程 序 中 的 标 号,32 位 地 址 常 量 或 32 位 常 量. type 当 expr 为 32 位 常 量 时, 可 用 type 指 示 expr 表 示 的 数 据 类 型. 如 下 CODE16 CODE32 DATA EQU 伪 指 令 的 作 用 类 似 于 C 语 言 中 的 #define. 用 于 为 一 个 常 量 定 义 名 称. 伪 指 令 应 用 举 例 如 下 ; T_bit EQU 0x20 ; 定 义 常 量 T_bit, 其 值 为 0x20 PLLCON EQU 0xE01FC080 ; 定 义 寄 存 器 PLLCON, 地 址 为 0Xe01F080 ABCD EQU label+8 ; 定 义 ABCD 为 label+8 EXPORT 和 GLOBAL EXPORT 声 明 一 个 符 号 可 以 被 其 它 文 件 引 用. 相 当 于 声 明 了 一 个 全 局 变 量. GLOBAL 与 EXPORT 相 同 指 令 格 式 : 第 81 页
EXPORT GLOBAL symbol{[weak]} symbol{[weak]} 其 中 symbol 要 声 明 的 符 号 名 称 [WEAK] 声 明 其 它 的 同 名 符 优 先 于 本 符 号 被 引 用. 伪 指 令 应 用 举 例 如 下 : EXPORT GLOBAL InitStack Vectors IMPORT 和 EXTERN IMJPORT 伪 指 令 指 示 编 译 器 当 前 的 符 号 不 是 在 本 源 文 件 中 定 义 的, 而 是 在 其 他 源 文 件 中 定 义 的, 在 本 源 文 件 中 可 能 引 用 该 符 号. EXTERN 与 IMPORT 相 同 指 令 格 式 : IMPORT EXTERN symbol{[weak]} symbol{[weak]} 其 中 symbol 要 声 明 的 符 号 名 称. [WEAK] 指 定 该 选 项 后, 如 果 symbol 在 所 有 的 源 程 序 中 都 没 有 被 定 义, 编 译 器 也 不 会 生 任 何 错 误 信 息, 同 时 编 译 器 也 不 会 到 当 前 没 有 被 INCLUDE 进 来 库 中 去 查 找 该 标 号. 使 用 IMPORT 或 EXTERN 声 明 外 部 标 号 时, 若 连 接 器 在 连 接 处 理 时 不 能 解 释 该 符 号, 而 伪 指 令 中 没 有 [WEAK] 选 项, 则 连 接 器 会 报 告 错 误, 若 伪 指 令 中 有 [WEAK] 选 项, 则 连 接 器 不 会 报 告 错 误, 而 是 进 行 下 面 的 操 作 : 1. 如 果 该 符 号 被 B 或 者 BL 指 令 引 用, 则 该 符 号 被 设 置 成 下 一 条 指 令 的 地 址, 该 B 或 者 BL 指 令 相 当 于 一 条 NOP 指 令. 2. 其 它 情 况 下 该 符 号 被 设 置 0 伪 指 令 应 用 举 例 如 下 IMPORT EXTERN InitStack Vectors 第 82 页
GET 和 INCLUDE GET 伪 指 令 将 一 个 源 文 件 包 含 到 当 前 源 文 件 中, 并 将 被 包 含 的 文 件 在 具 当 前 位 置 进 行 汇 编 处 理 INCLUDE 与 GFT 同 义 指 令 格 式 GET INCLUDE filename filename 其 中 filename 要 包 含 的 源 文 件 名, 可 以 使 用 路 径 信 息. GET 伪 指 令 通 常 用 于 包 含 一 些 宏 定 义 或 常 量 定 义 的 源 文 件. 如 用 EQU 定 义 的 常 量, 用 MAP 和 FIELD 定 义 的 结 构 化 的 数 据 类 型, 这 样 的 源 文 件 类 似 于 C 语 言 中 的 头 文 件,GET,INCLUDE 伪 指 令 不 能 用 来 包 含 目 标 文 件, 而 INCBIN 伪 指 令 可 以 包 含 目 标 文 件. 伪 指 令 应 用 举 例 如 下 INCLUDE LPC2106.inc INCBIN INCBIN 伪 指 令 将 一 个 文 件 包 含 到 当 前 源 文 件 中, 而 被 包 含 的 文 件 不 进 行 汇 编 处 理. 指 令 格 式 : INCBIN filename 其 中 filename 要 包 含 的 源 文 件 名, 可 以 使 用 路 径 信 息. 通 常 可 以 使 用 INCBIN 将 一 个 执 行 文 件 或 者 任 意 数 据 包 含 到 当 前 文 件 中, 被 包 含 的 执 行 文 件 或 数 据 将 被 原 封 不 动 地 放 下 当 前 文 件 中, 编 译 器 从 INCBIN 伪 指 令 后 面 开 始 继 续 处 理. 伪 指 令 应 用 举 例 如 下 INCBIN charlib.bin KEEP KEEP 伪 指 令 指 示 编 译 器 保 留 符 号 表 中 的 局 部 符 号. 伪 指 令 格 式 第 83 页
KEEP 其 中 {symbol} symbol 要 保 留 的 局 部 标 号. 若 没 有 此 项, 则 除 了 基 于 寄 存 器 处 的 所 有 符 号 将 包 含 在 目 标 文 件 的 符 号 表 中. NOFP NOFP 伪 指 令 用 于 禁 止 源 程 序 中 包 含 浮 点 运 算 指 令. 伪 指 令 格 式. NOFP REQUIRE REQUIRE 伪 指 令 指 定 段 之 间 的 依 赖 关 系. 伪 指 令 格 式 REQUIRE label 其 中 label 所 需 要 的 标 号 的 名 称. 当 进 行 链 接 处 理 时, 包 含 了 REQUIRE label 伪 指 令 的 源 文 件, 则 定 义 label 的 源 文 件 也 被 包 含. PEQUIRE8 和 PRESERVE8 PEQUIRE8 伪 指 令 指 示 当 前 文 件 请 求 堆 栈 为 8 字 节 对 齐, PRESERVE8 伪 指 令 指 示 当 前 文 件 保 持 堆 栈 为 8 字 节 对 齐. 伪 指 令 格 式. PEQUIRE8 PRESERVE8 链 接 器 保 证 要 求 8 字 节 对 齐 的 堆 栈 只 能 被 堆 栈 为 8 字 的 对 齐 的 代 码 调 用. RN RN 伪 指 令 用 于 给 一 个 特 殊 的 寄 存 器 命 名. 第 84 页
伪 指 令 格 式 name RN expr 其 中 name 给 寄 存 器 定 义 的 名 称. expr 寄 存 器 编 号 伪 指 令 应 用 举 例 如 下 COUNT RN 6 ; 定 义 寄 存 器 R6 为 COUT Count1 RN R7 ; 定 义 寄 存 器 R7 为 Cout1 ROUT ROUT 伪 指 令 用 于 定 义 局 部 标 号 的 有 效 范 围. 伪 指 令 格 式 如 下. {name} ROUT 其 中 name 所 定 义 的 作 用 范 围 的 名 称. 当 没 有 使 用 ROUT 伪 指 令 时, 局 部 标 号 的 作 用 范 围 为 其 所 在 段.ROUT 伪 指 令 的 作 用 范 围 在 本 ROUT 伪 指 令 和 下 一 个 ROUT 伪 指 令 之 间 ( 指 同 一 段 中 的 ROUT 伪 指 令.) 伪 指 令 应 用 举 例 如 下. routinea ROUT ; 定 义 局 部 标 号 的 有 效 范 围, 名 称 为 routinea 3routineA ;routinea 范 围 内 的 局 部 标 号 3 BEQ %4routineA ; 若 条 件 成 立, 跳 转 到 routinea 范 围 内 的 局 部 标 号 4 BEG %3 ; 若 条 件 成 立, 跳 转 到 routinea 范 围 内 的 局 部 标 号 3 4routineA ;routinea 范 围 内 的 局 部 标 号 4 otherstuff ROUT ; 定 义 新 的 局 部 标 号 的 有 效 范 围 第 85 页
ARM 伪 指 令 ARM 伪 指 令 有 ADR,ADRL,LDR,NOP,LDFD,LDFS. ADR 为 小 范 围 的 地 址 读 取 伪 指 令.ADR 指 令 将 基 于 PC 相 对 偏 移 的 地 址 值 或 基 于 寄 存 器 相 对 偏 移 的 地 址 值 读 取 到 寄 存 器 中, 当 地 址 值 是 非 字 对 齐 时, 取 值 范 围 -255~255 字 节 之 间, 当 地 址 值 是 字 对 齐 时, 取 值 范 围 -1020~1020 字 节 之 间 ADRL 为 中 等 范 围 的 地 址 读 取 伪 指 令.ADRL 指 令 将 基 于 PC 相 对 偏 移 的 地 址 值 或 基 于 寄 存 器 相 对 偏 移 的 地 址 值 读 取 到 寄 存 器 中, 当 地 址 值 是 非 字 对 齐 时, 取 值 范 围 -64K~64K 字 节 之 间, 当 地 址 值 是 字 对 齐 时, 取 值 范 围 -256K~256K 字 节 之 间 LDR 为 大 范 围 的 地 址 读 取 伪 指 令.LDR 伪 指 令 用 于 加 载 32 位 的 立 即 数 或 一 个 地 址 值 到 指 定 寄 存 器. 若 汇 编 器 将 常 量 放 入 文 字 池, 并 使 用 一 条 程 序 相 对 偏 移 的 LDR 指 令 从 文 字 池 读 出 常 量, 则 从 PC 到 文 字 池 的 偏 移 量 必 须 小 于 4KB. NOP 为 空 操 作 伪 指 令.NOP 伪 指 令 在 汇 编 时 将 会 被 代 替 成 ARM 中 的 空 操 作, 比 如 可 能 为 MOV R0,R0 指 令 等. LDFD 伪 指 令 将 一 个 双 精 度 浮 点 数 常 数 放 进 一 个 浮 点 数 寄 存 器. 伪 指 令 格 式 : LDFD fx,=expr 第 86 页
其 中 fx 浮 点 数 寄 存 器 expr 双 精 度 浮 点 数 值. 伪 指 令 应 用 举 例 如 下 LDFD f1,=0.12 LDFS 伪 指 令 将 一 个 单 精 度 浮 点 数 常 数 放 进 一 个 浮 点 寄 存 器. 伪 指 令 格 式 : LDFS fx,=expr 其 中 fx 浮 点 数 寄 存 器 expr 单 精 度 浮 点 数 值. 伪 指 令 应 用 举 例 如 下 LDFS f1,=o.12 Thumb 伪 指 令 Thumb 伪 指 令 有 ADR,LDR,NOP. ADR 为 小 范 围 的 地 址 读 取 伪 指 令.ADR 指 令 将 基 于 PC 相 对 偏 移 的 地 址 值 读 取 到 寄 存 器 中, 偏 移 量 必 须 是 正 数 并 小 于 1KB. LDR 为 大 范 围 的 地 址 读 取 伪 指 令.LDR 伪 指 令 用 于 加 载 32 位 的 立 即 数 或 一 个 地 址 值 到 指 定 寄 存 器. 若 汇 编 器 将 常 量 放 入 文 字 池, 并 使 用 一 条 程 序 相 对 偏 移 的 LDR 指 令 从 文 字 池 读 出 常 量, 则 从 PC 到 文 字 池 的 偏 移 量 必 须 是 正 数 并 小 于 1KB 第 87 页
NOP 为 空 操 作 伪 指 令.NOP 伪 指 令 在 汇 编 时 将 会 被 代 替 成 ARM 中 的 空 操 作, 比 如 可 能 为 MOV R8,R8 指 令 等. ARM 汇 编 程 序 设 计 文 件 格 式 ARM 源 程 序 文 件 ( 即 源 文 件 ) 为 文 件 格 式, 可 以 使 用 任 一 文 本 编 辑 器 编 写 程 序 代 码. 一 般 地,ARM 源 程 序 文 件 名 的 后 缀 名 如 下 表 : 程 序 汇 编 引 入 文 件 C 程 序 头 文 件 文 件 名 *.S *.INC *.C *.H 在 一 个 项 目 中, 至 少 要 有 一 个 汇 编 源 文 件 或 C 程 序 文 件, 可 以 有 多 个 汇 编 源 文 件 或 多 个 C 程 序 文 件, 或 者 C 程 序 文 件 和 汇 编 文 件 两 者 的 组 合. ARM 汇 编 的 一 些 规 范 汇 编 语 句 格 式 ARM 汇 编 中, 所 有 标 号 必 须 在 一 行 的 顶 格 书 写, 其 后 面 不 要 添 加 :, 而 所 有 指 令 均 不 能 顶 格 书 写 ARM 汇 编 器 对 标 识 符 大 小 写 敏 感, 书 写 标 号 及 指 令 时 字 母 大 小 写 要 一 致, 在 ARM 汇 编 程 序 中, 一 个 ARM 指 令 伪 指 令 寄 存 器 名 可 以 全 部 为 大 写 字 母, 也 可 以 全 部 为 小 写 字 母, 但 不 要 大 小 写 混 合 使 用 注 释 使 用 ;, 注 释 内 容 由 ; 开 始 到 此 行 结 束, 注 释 可 以 在 一 行 的 顶 格 书 写 格 式 :[ 标 号 ] < 指 令 条 件 S> < 操 作 数 >[; 注 释 ] 源 程 序 中 允 许 有 空 行, 适 当 地 插 入 空 行 可 以 提 高 源 代 码 的 可 读 性 如 果 单 行 太 长, 第 88 页
可 以 使 用 字 符 \ 将 其 分 行, \ 后 不 能 有 任 何 字 符, 包 括 空 格 和 制 表 符 等 对 于 变 量 的 设 置, 常 量 的 定 义, 其 标 识 符 必 须 在 一 行 的 顶 格 书 写 汇 编 指 令 正 确 的 例 子 和 错 误 的 例 子 如 下 : 正 确 的 例 子 : Str1 SETS My string1. ; 设 置 字 符 串 变 量 Str1 Count RN R0 ; 定 义 寄 存 器 名 Count USR_STACK EQU 64 ; 定 义 常 量 START LDR R0,=0x1123456 ;R0=0x123456H MOV R1,#0 LOOP MOV R2,#3 错 误 的 例 子 : START MOV R0,#1 ; 标 号 START 没 有 顶 格 写 ABC: MOV R1,#2 ; 标 号 后 不 能 带 : MOV R2,#3 ; 命 令 不 允 许 顶 格 书 写 loop Mov R2,#3 ; 指 令 中 大 小 写 混 合 B Loop ; 无 法 跳 转 到 Loop 标 号 标 号 在 ARM 汇 编 中, 标 号 代 表 一 个 地 址, 段 内 标 号 的 地 址 在 汇 编 时 确 定, 而 段 外 标 号 的 地 址 值 在 连 接 时 确 定 根 据 标 号 的 生 成 方 式, 可 以 有 以 下 3 钟 : 基 于 PC 的 标 号 基 于 PC 的 标 号 时 位 于 目 标 指 令 前 的 标 号 或 程 序 中 的 数 据 定 义 伪 指 令 前 的 标 号, 这 种 标 号 在 汇 编 时 将 被 处 理 成 PC 值 加 上 或 减 去 一 个 数 字 常 量 它 常 用 于 表 示 跳 转 指 令 的 第 89 页
目 标 地 址, 或 者 代 码 段 中 所 嵌 入 的 少 量 数 据 基 于 寄 存 器 的 标 号 基 于 寄 存 器 的 标 号 通 常 用 MAP 和 FILED 伪 指 令 定 义, 也 可 以 用 于 EQU 伪 指 令 定 义, 这 种 标 号 在 汇 编 时 被 处 理 成 寄 存 器 的 值 加 上 或 减 去 一 个 数 字 常 量 它 常 用 于 访 问 位 于 数 据 段 中 的 数 据 绝 对 地 址 绝 对 地 址 是 一 个 32 为 的 数 字 量, 它 可 以 寻 址 的 范 围 为 0~2 32-1, 可 以 直 接 寻 址 整 个 内 存 空 间 局 部 标 号 局 部 标 号 主 要 用 于 局 部 范 围 代 码 中, 在 宏 定 义 也 是 很 有 用 的 局 部 标 号 是 一 个 0~ 99 之 间 的 十 进 制 数 字, 可 重 复 定 义, 局 部 标 号 后 面 可 以 紧 接 一 个 通 常 表 示 该 局 部 变 量 作 用 范 围 的 符 号 局 部 变 量 的 作 用 范 围 为 当 前 段, 也 可 以 用 伪 指 令 ROUT 来 定 义 局 部 标 号 的 作 用 范 围 局 部 标 号 定 义 格 式 :N{routname} 其 中 :N routname 局 部 标 号, 为 0~99 局 部 标 号 作 用 范 围 的 名 称, 由 ROUT 伪 指 令 定 义 局 部 标 号 引 用 格 式 : %{F B}{A T} N{routname} 其 中 : % 表 示 局 部 标 号 引 用 操 作 F B A T 指 示 编 译 器 只 向 前 搜 索 指 示 编 译 器 只 向 后 搜 索 指 示 编 译 器 搜 索 宏 的 所 有 嵌 套 层 次 指 示 编 译 器 搜 索 宏 的 当 前 层 如 果 F 和 B 都 没 有 指 定, 则 编 译 器 先 向 前 搜 索, 再 向 后 搜 索 如 果 A 和 T 都 没 有 指 定, 编 译 器 搜 索 所 有 从 宏 的 当 前 层 次 到 宏 的 最 高 层 次, 比 当 前 层 次 的 层 次 不 再 搜 索 第 90 页
如 果 指 定 了 routname, 编 译 器 向 前 搜 索 最 近 的 ROUT 伪 指 令, 若 routname 与 该 ROUT 伪 指 令 定 义 的 名 称 不 匹 配, 编 译 器 报 告 错 误, 汇 编 失 败 示 例 如 下 : routinta ROUT 3routineA BEQ %4routineA BGE %3 4routineA otherstuff ROUT 符 号 在 ARM 汇 编 中, 符 号 可 以 代 表 地 址 变 量 数 字 常 量 当 符 号 代 表 地 址 时 又 称 为 标 号, 符 号 就 是 变 量 的 变 量 名 数 字 常 量 的 名 称 标 号, 符 号 的 命 名 规 则 如 下 : 1 符 号 由 大 小 写 字 母 数 字 以 及 下 划 线 组 成 ; 2 除 局 部 标 号 以 数 字 开 头 外, 其 它 的 符 号 不 能 以 数 字 开 头 ; 3 符 号 区 分 大 小 写, 且 所 有 字 符 都 是 有 意 义 的 ; 4 符 号 在 其 作 用 域 范 围 你 必 须 是 唯 一 的 ; 5 符 号 不 能 与 系 统 内 部 或 系 统 预 定 义 的 符 号 同 名 ; 6 符 号 不 要 与 指 令 助 记 符 伪 指 令 同 名 常 量 数 字 常 数 数 字 常 量 有 三 种 表 示 方 式 : 十 进 制 数, 如 :12,5,876,0; 十 六 进 制 数, 如 0x4387,0xFF0, 0x1; 第 91 页
n 进 制 数, 用 n-xxx 表 示, 其 中 n 为 2~9,XXX 为 具 体 的 数 如 2-010111,8-4363156 等 字 符 常 量 字 符 常 量 由 一 对 单 引 号 及 中 间 字 符 串 表 示, 标 准 C 语 言 中 的 转 义 符 也 可 使 用 如 果 需 要 包 含 双 引 号 或 $, 必 须 使 用 和 $$ 代 替 如 下 : Hello SETS Hello World! Errorl SETS The parameter VFH error$$2 布 尔 常 量 布 尔 常 量 的 逻 辑 真 为 {TRUE}, 逻 辑 假 为 {FALSE}. 如 下 : testno SETS {FALSE} 段 定 义 ARM 汇 编 程 序 设 计 采 用 分 段 式 设 计, 一 个 ARM 源 程 序 至 少 需 要 一 个 代 码 段, 大 的 程 序 可 以 包 含 多 个 代 码 段 及 数 据 段. ARM 汇 编 程 序 经 过 汇 编 处 理 后 生 成 一 个 可 执 行 的 映 象 文 件, 该 文 件 通 常 包 含 下 面 3 部 分 内 容 : 一 个 或 多 代 码 段. 代 码 段 通 常 是 只 读 的. 零 个 或 多 个 包 含 初 始 化 值 的 数 据 段. 这 些 数 据 段 通 常 是 可 读 写 的. 零 个 或 多 个 不 包 含 初 始 值 的 数 据 段. 这 些 数 据 被 初 始 化 为 0, 通 常 中 可 读 写 的. 连 接 器 根 据 一 定 的 规 则 将 各 个 段 安 排 到 内 存 中 的 相 应 位 置. 源 程 序 中 段 之 间 的 相 邻 关 系 与 执 行 的 映 象 文 件 中 段 之 间 的 相 邻 关 系 并 不 一 定 相 同. 代 码 段 的 例 子 如 下 : AREA Hello,CODE,READONLY ; 声 明 代 码 段 Hello ENTRY ; 程 序 入 口 ( 调 试 用 ) START MOV MOV R7,#10 R6,#5 第 92 页
ADD R6,R6,R7 ;R6=R6+R7 B ; 死 循 环 END 每 一 个 汇 编 文 件 都 要 以 END 结 束, 包 括 *INC 文 件, 否 则 编 译 会 有 警 告. 数 据 段 的 例 子 如 下 : AREA DataArea,DATA,NOINIT,ALLGN=2 DISPBUF SPACE 100 RCVBUF SPACE 100 宏 定 义 及 其 作 用 使 用 宏 定 义 可 以 提 高 程 序 的 可 读 性, 简 化 程 序 代 码 和 同 步 修 改.ARM 宏 定 义 与 标 准 C 的 #define 相 似, 只 在 源 程 序 中 进 行 字 符 代 换. 宏 定 义 从 MACRO 伪 指 令 开 始, 到 MEND 结 束, 并 可 以 使 用 参 数. 宏 要 先 定 义, 然 后 再 使 用. 使 用 时 直 接 书 写 宏 名, 并 根 据 对 应 的 宏 定 义 格 式 设 置 输 入 参 数 或 书 写 标 号 等. 当 源 程 序 被 汇 编 时, 汇 编 编 译 器 将 展 开 每 一 个 宏 调 用, 用 宏 定 义 体 代 替 程 序 中 的 宏 调 用, 并 使 用 实 际 的 参 数 值 代 替 宏 定 义 时 的 形 式 参 数. 程 序 程 序 清 单 见 后, 程 序 中 定 义 了 一 个 宏 CALL, 用 于 调 用 子 程 序, 调 用 时 设 置 所 要 调 用 的 子 程 序 名 $Function 及 两 个 入 口 参 数 $dat1 和 $dat2. 由 于 宏 定 义 体 中 使 用 的 是 MOV 指 令, 所 以 $dat1 参 数 只 能 为 8 位 图 的 立 即 数 或 通 用 寄 存 器. 宏 应 用 的 例 子 : MACRO CALL ; 宏 定 义 $Function,$dat1,$dat2 ; 宏 名 称 为 CALL, 带 3 个 参 数 IMPORT $Function ; 声 明 外 部 子 程 序 MOV R0,$dat1 ; 设 置 子 程 序 参 数,R0=$dat1 MOV R1,$dat2 BL Function ; 调 用 子 程 序 MEND ; 宏 定 义 结 束 第 93 页
CALL FADD1,#3,#2 ; 宏 调 用 汇 编 预 处 理 后, 宏 调 用 将 被 展 开, 程 序 清 单 如 下 : IMPORT MOV MOV BL FADD1 R0,#3 R1,#3 FADD1 子 程 序 的 调 用 使 用 BL 指 令 进 行 调 用, 该 指 令 会 把 返 回 的 PC 值 保 存 在 LR, 示 例 如 下 : BL DLEAY DELAY MOV PC,LR 当 子 程 序 执 行 完 毕 后, 使 用 MOV,B/BX,STMFD 等 指 令 返 回, 当 然 STMFD 要 与 LDMFD 配 套 使 用, 子 程 序 返 回 的 方 法 : MOV PC,LR 或 B LR 或 BX LR 或 STMFD SP!{R0-R7,PC } ARM7TDMI(-S) 是 没 有 BLX 指 令 的, 但 是 可 以 通 过 几 条 程 序 实 现 其 功 能, 模 拟 BLX 指 令 如 下 : ADR R1,DELAY+1 MOV LR,PC ; 保 存 返 回 地 址 到 LR BX R1 ; 跳 转 并 切 换 指 令 集 第 94 页
数 据 比 较 跳 转 汇 编 程 序 可 以 使 用 CMP 指 令 进 行 两 个 数 据 比 较, 然 后 调 高 相 应 的 ARM 条 件 码, 实 现 跳 转. 代 码 例 子 如 下 : CMP R5,#10 BEQ DOEQUAL ; 若 R5 为 10, 则 跳 转 到 DOEQUAL CMP R1,R2 ADDHI R1,R1,#10 ; 若 R1>R2, 则 R1=R1+10 ADDLS R1,R1,#5 ; 若 R1<=R2, 则 R1=R1+5 ANDS R1,R1,#0x80 ;R1=R1&0x80, 并 设 置 相 应 标 志 位 BNE WAIT ; 若 R1 的 d7 位 为 则 跳 转 到 WAIT 循 环 下 面 的 代 码 为 循 环 程 序 的 例 子. 例 子 指 定 循 环 次 数, 每 循 环 一 次 进 行 减 1 操 作, 并 判 断 结 果 是 否 为 0, 若 为 0 则 退 出 循 环. MOV R1,#10 LOOP ; 循 环 体 SUBS BNE R1,R1,#1 LOOP 数 据 块 复 制 下 : 程 序 可 以 使 用 存 储 器 访 问 指 令 LDM/STM 指 令 进 行 读 取 和 存 储, 数 据 块 复 制 示 例 如 LDR R0,=DATA_DST ; 指 向 数 据 目 标 地 址 第 95 页
LDR R1,=DATA_SRC ; 指 向 数 据 源 地 址 MOV R10,#10 ; 复 制 数 据 个 数 为 10*N 个 字 LOOP LDMIA R1!,{R2-R9} ;N 为 LDM/STM 指 令 操 作 数 据 个 数 STMIA R0!,{R2-R9} SUBS BNE R10,R10,#1 LOOP 栈 操 作 ARM 使 用 存 储 器 访 问 指 令 LDM/STM 实 现 栈 操 作, 用 于 子 程 序 寄 存 器 保 存. 注 意, 使 用 堆 栈 时, 要 先 分 配 好 堆 栈 空 间, 设 置 好 寄 存 器 R13( 即 堆 栈 指 针 SP), 否 则 操 作 失 败. OUTDAT STMFD SP!{R0-R7,LR} BL DELAY LDMFD SP!{R0-R7,PC} 特 殊 寄 存 器 定 义 及 应 用 基 于 ARM 核 的 芯 片 一 般 有 片 内 外 设, 它 们 通 过 其 特 殊 寄 存 器 访 问. 片 内 外 设 的 使 用 示 例 如 下 : WDTC EQU 0xE000000 ; 寄 存 器 定 义 LDR MOV R0,=WDTC R1,#0x12 STR R1,[R0] ;WDTC=0x12 第 96 页
散 转 功 能 散 转 是 汇 编 程 序 常 用 的 一 种 算 法, 其 示 例 如 下 : CMP R0,#MAXINDEX ; 判 断 索 引 号 是 否 超 出 最 大 索 引 值 ADDLO PC,PC,R0,LSL #2 ; 若 没 有 超 出, 则 跳 转 到 相 应 位 置 B ERROR ; 若 已 经 超 出, 则 进 行 出 错 处 理 ; 散 转 表, 对 应 索 引 号 为 0~N B B B FUN1 FUN2 FUN3 查 表 操 作 查 表 操 作 是 汇 编 程 序 常 用 的 一 种 操 作, 其 示 例 如 下 : LDR R3,=DISP_TAB ; 取 得 表 头 LDR R2,[R3,R5,LSL #2] ; 根 据 R5 的 值 查 表, 取 出 相 应 的 值 ; 下 表 为 0--F 的 字 模 DISR_TAB DCD 0xC0,0xF9,0xA4,0x99,0x92 DCD DCD 0x82,0xF8,0x80,0x90,0x88,0x83 0xC6,0xa1,0x86,0x8E,0xFF 长 跳 转 ARM 的 B 和 BL 指 令 不 能 全 空 间 跳 转, 但 通 过 对 PC 进 行 赋 值, 实 现 32 位 地 址 的 跳 转 / 调 用, 示 例 如 下 : ADD LR,PC,#4 ; 保 存 返 回 地 址, 即 RET_FUN LDR PC,[PC,#-4] ; 跳 转 到 LADR_FUN DCD LADR_FUN 第 97 页
RET_FUN 也 可 使 用 伪 指 令 LDR PC,=LADR_FUN 实 现 长 跳 转 对 信 号 量 的 支 持 ARM 提 供 一 条 内 存 与 寄 存 器 交 换 的 指 令 SWP 用 于 支 持 信 号 量 的 操 作, 实 现 系 统 任 务 之 间 的 同 步 或 互 斥, 其 使 用 的 例 子 如 下 : DISP_SEM EQU 0x40002A00 DISP_WAIT MOV LDR R1,#0 R0,=DISP_SEM SWP R1,R1[R0] ; 取 出 信 号 量, 并 设 置 其 为 0 CMP R1,#0 ; 判 断 是 否 有 信 号 BEQ DISP_WAIT ; 若 没 有 信 号, 则 等 待 伪 指 令 使 用 LDR 伪 指 令 和 NOP 伪 指 令 应 用 例 子 代 码 如 下 : LDR R1,=0x12345678 LDR R0,=LDE_TAB NOP B ; 加 载 32 位 立 即 数 ; 加 载 标 号 地 址 ; 空 指 令 ; 死 循 环 一 个 完 整 的 例 子 下 面 是 汇 编 程 序 完 整 的 例 子 : ABC EQU 0x12 ; 声 明 一 个 代 码 段 Example AREA Example,CODE,READONLY ENIRY 第 98 页
CODE32 ADR R0,Thumb_START+1 ; 装 载 地 址, 并 设 置 d0 位 为 1 BX R0 ; 切 换 到 Thumb 状 态 CODE16 ; 声 明 16 位 代 码 (Thumb) Thumb_START MOV R1,#ABC ADD R1,R1,#0x10 B Thumb_START END 外 围 部 件 控 制 在 32 位 的 ARM 核 芯 片 中, 其 外 围 部 件 的 控 制 寄 存 器 中, 一 般 会 设 置 置 位 / 复 位 寄 存 器, 这 样 可 以 方 便 的 实 现 位 操 作, 而 不 会 影 响 其 它 位, 如 IOSET=0x01 只 会 将 P0.1 的 置 位, 而 其 它 I/O 状 态 不 变, 另 外,ARM 存 储 / 保 存 指 令 具 有 前 偏 移 功 能, 所 以 对 外 围 部 件 的 控 制 寄 存 器 进 行 操 作 时 可 使 用 此 功 能, 避 免 了 每 次 都 加 载 寄 存 器 地 址 的 操 作 示 例 如 下 : LDR MOV R0,=GPIO_BASE R1,#0x00 STR R1,[R0,#0x04] ;IOSET=0x00 MOV R1,#0x10 STR R1,[R0,#0x0C] ;IOCLR=0x101 三 级 流 水 线 介 绍 ARM7TDM(-S) 使 用 三 级 流 水 线 执 行 指 令, 第 一 阶 段 从 内 存 中 取 回 的 指 令, 第 二 阶 段 开 始 解 码, 而 第 三 阶 段 实 际 执 行 指 令. 故 此, 程 序 计 数 器 总 是 超 出 当 前 执 行 的 指 令 两 条 指 令.( 在 为 跳 转 指 令 计 算 偏 移 量 时 必 须 计 算 在 内 ). 因 为 有 这 个 流 水 线, 在 跳 转 时 丢 失 2 个 指 令 周 期 ( 因 为 要 重 新 添 满 流 水 线 ). 所 以 最 好 利 用 条 件 执 行 指 令 来 避 免 浪 费 周 期. 条 件 跳 转 示 例 : 第 99 页
CMP BEQ MOV MOV R0,#0 LOOP1 R1,#0x10 R2,#0x88 LOOP1 可 以 写 为 更 有 效 的 : CMP MOVNE MOVNE R0,#0 R1,#0x10 R2,#0x88 C 与 汇 编 混 合 编 程 在 需 要 C 与 汇 编 混 合 编 程 时, 若 汇 编 代 码 较 结, 则 可 使 用 直 接 内 嵌 汇 编 的 方 法 混 合 编 程 ; 否 则, 可 以 将 汇 编 文 件 以 文 件 的 形 式 加 入 项 目 中, 通 过 ATPCS 规 定 与 C 程 序 相 互 调 用 及 访 问. ATPCS, 即 ARM,Thumb 过 程 调 用 标 准 (ARM/Thumb Procedure Call Standard), 它 规 定 了 一 些 子 程 序 间 调 用 的 基 本 规 则, 如 子 程 序 调 用 过 程 中 的 寄 存 器 的 使 用 规 则, 堆 栈 的 使 用 规 则, 参 数 的 传 递 规 则 等. 内 嵌 汇 编 在 C 程 序 嵌 入 汇 编 程 序, 可 以 实 现 一 些 高 级 语 言 没 有 的 功 能, 提 高 程 序 执 行 效 率.armcc 编 译 器 的 内 嵌 汇 编 器 支 持,ARM 指 令 集,tcc 编 译 器 的 内 嵌 汇 编 支 持 Thumb 指 令 集. 内 嵌 汇 编 的 语 法 : asm { 第 100 页
指 令 [; 指 令 ] /* 注 释 */ [ 指 令 ] } 嵌 入 汇 编 程 序 的 例 子 如 下 所 示, 其 中 enable_irq 函 数 为 使 能 IRQ 中 断, 而 disable_irq 函 数 为 关 闭 IRQ 中 断. 使 能 / 禁 能 IRQ 中 断 : inline void enable_irq(void) { int tmp _asm // 嵌 入 汇 编 代 码 { MRS tmp,cpsr BIC tmp,tmp,#0x80 // 读 取 CPSR 的 值 // 将 IRQ 中 断 禁 止 位 I 清 零, 即 允 许 IRQ 中 断 MSR CPSR_c,tmp // 设 置 CPSR 的 值 } } inline void disable_irq(void) { int tmp; _asm { MRS tmp,cpsr ORR tmp,tmp,#0x80 MSR CPSR_c,tmp } } 另 外 一 个 嵌 入 汇 编 程 序 的 例 子 如 下 所 示, 其 中 my_strcpy 函 数 是 字 符 串 复 制 函 第 101 页
数,src 为 源 字 符 串 指 针,dst 为 目 标 字 符 串 指 针 制 操 作 全 部 由 嵌 入 的 汇 编 代 码 实 现. 在 主 程 序 中, 可 以 使 用 my_strcpy(a,b) 来 调 用 函 数, 还 可 以 使 用 嵌 入 汇 编 方 法 进 行 调 用, 嵌 入 汇 编 的 代 码 先 要 设 置 入 口 参 数 R0,R1, 然 后 使 用 BL my_strcpy,{r0,r1} 指 令 调 用 函 数, 其 中, 输 入 寄 存 器 列 表 为 {R0,R1}, 没 有 输 出 寄 存 器 列 表. 字 符 串 复 制 : #include <stdio.h> void my_strcpy(const char*src, char*dst) { int ch; _asm { loop: #ifndef_thumb //ARM 指 令 版 本 LDRB ch,[src],#1 STRB ch,[dst],#1 #else //Thumb 指 令 版 本 LDRB ch,[src] ADD src,#1 STRB ch,[dst] ADD dst,#1 #endif CMP BNE ch,#0 loop } } int main(void) 第 102 页
{ const char*a= Hello world! char b[20] //my_strcpy(a,b); _asm { MOV R0,a // 设 置 入 口 参 数 MOV R1,b BL my_strcpy,{r0,r1} // 调 用 my_strcpy() 函 数 } printf( Original string: %s \n, a); // 显 示 my_strcpy() 函 数 字 符 串 复 制 结 果 printf( Copied string: %s \n, b); return(0); } 内 嵌 汇 编 的 指 令 用 法 操 作 数. 内 嵌 的 汇 编 指 令 中 作 为 操 作 数 的 寄 存 器 和 常 量 可 以 是 表 达 式. 这 些 表 达 式 可 以 是 char,short 或 int 类 型, 而 且 这 些 表 达 式 都 是 作 为 无 符 号 数 进 行 操 作. 若 需 要 带 符 号 数, 用 户 需 要 自 己 处 理 与 符 号 有 关 的 操 作. 编 译 器 将 会 计 算 这 些 表 达 式 的 值, 并 为 其 分 配 寄 存 器. 物 理 寄 存 器. 内 嵌 汇 编 中 使 用 物 理 寄 存 器 有 以 下 限 制 ; 不 能 直 接 向 PC 寄 存 器 赋 值, 程 序 跳 转 只 能 使 用 B 或 BL 指 令 实 现 使 用 物 理 寄 存 器 的 指 令 中, 不 要 使 用 过 于 复 杂 的 C 表 达 式. 因 为 表 达 式 过 于 复 杂 时, 将 会 需 要 较 多 的 物 理 寄 存 器. 这 些 寄 存 器 可 能 与 指 令 中 的 物 理 寄 存 器 使 用 冲 突. 编 译 器 可 能 会 使 用 R12 或 R13 存 放 编 译 的 中 间 结 果, 在 计 算 表 达 式 的 值 时 可 能 会 将 寄 存 器 R0~R3,R12 和 R14 用 于 子 程 序 调 用. 因 此 在 内 嵌 的 汇 编 指 令 中, 不 要 将 这 些 寄 存 器 同 时 指 定 为 指 令 中 的 物 理 寄 存 器. 通 常 内 嵌 的 汇 编 指 令 中 不 要 指 定 物 理 寄 存 器, 因 为 这 可 能 会 影 响 编 译 器 分 配 寄 第 103 页
存 器, 进 而 影 响 代 码 的 效 率. 常 量. 在 内 嵌 汇 编 指 令 中, 常 量 前 面 的 # 可 以 省 略. 指 令 展 开. 内 嵌 汇 编 指 令 中, 如 果 包 含 常 量 操 作 数, 该 指 令 有 可 能 被 内 嵌 汇 编 器 展 开 成 几 条 指 令. 标 号.C 程 序 中 的 标 号 可 以 被 内 嵌 的 汇 编 指 令 使 用, 但 是 只 有 指 令 B 可 以 使 用 C 程 序 中 的 标 号, 而 指 令 BL 则 不 能 使 用. 内 存 单 元 的 分 配. 所 有 的 内 存 分 配 均 由 C 编 译 器 完 成, 分 配 的 内 存 单 元 通 过 变 量 供 内 嵌 汇 编 器 使 用. 内 嵌 汇 编 器 不 支 持 内 嵌 汇 编 程 序 中 用 于 内 存 分 配 的 伪 指 令. SWI 和 BL 指 令. 在 内 嵌 的 SWI 和 BL 指 令 中, 除 了 正 常 的 操 作 数 域 外, 还 必 须 增 加 以 下 3 个 可 选 的 寄 存 器 列 表 : 第 1 个 寄 存 器 列 表 中 的 寄 存 器 用 于 输 入 的 参 数. 第 2 个 寄 存 器 列 表 中 的 寄 存 器 用 于 存 储 返 回 的 结 果 第 3 个 寄 存 器 列 表 中 的 寄 存 器 的 内 容 可 能 被 被 调 用 的 子 程 序 破 坏, 即 这 些 寄 存 器 是 供 被 调 用 的 子 程 序 作 为 工 作 寄 存 器 内 嵌 汇 编 器 与 armasm 汇 编 器 的 差 异 内 嵌 汇 编 器 不 支 持 通 过. 指 示 符 或 PC 获 取 当 前 指 令 地 址 ; 不 支 持 LDR Rn,=expr 伪 指 令, 而 使 用 MOV Rn,expr 指 令 向 寄 存 器 赋 值 ; 不 支 持 标 号 表 达 式 ; 不 支 持 ADR 和 ADRL 伪 指 令 ; 不 支 持 BX 指 令 ; 不 能 向 PC 赋 值. 使 用 0x 前 缀 代 替 &, 表 示 十 六 进 制 数. 使 用 8 位 移 位 常 数 导 致 CPSR 的 标 志 更 新 时,N Z C 和 V 标 志 中 的 C 不 具 有 真 实 意 义. 内 嵌 汇 编 注 意 事 项 必 须 小 心 使 用 物 理 寄 存 器, 如 R0~R3,IP,LR 和 CPSR 中 的 N,Z,C,V 标 志 位. 因 为 计 算 汇 编 代 码 中 的 C 表 达 式 时, 可 能 会 使 用 这 些 物 理 寄 存 器, 并 会 修 改 N,Z,C,V 标 志 位. 如 : asm { MOV R0,x 第 104 页
ADD y,r0,x/y // 计 算 x/y 时 R0 会 被 修 改 } 在 计 算 x/y 时 R0 会 被 修 改, 从 而 影 响 R0+x/y 的 结 果. 用 一 个 C 程 序 的 变 量 代 替 R0 就 可 以 解 决 这 个 问 题 : asm { MOV var,x ADD y,var,x/y } 内 嵌 汇 编 器 探 测 到 隐 含 的 寄 存 器 冲 突 就 会 报 错. 不 要 使 用 寄 存 器 代 替 变 量. 尽 管 有 时 寄 存 器 明 显 对 应 某 个 变 量, 但 也 不 能 直 接 使 用 寄 存 器 代 替 变 量. int bad_f(int x) //x 存 放 在 R0 中 { asm { ADD R0,R0,#1 // 发 生 寄 存 器 冲 突, 实 际 上 x 的 值 没 有 变 化 } return(x); } 尽 管 根 据 编 译 器 的 编 译 规 则 似 乎 可 以 确 定 R0 对 应 x, 但 这 样 的 代 码 会 使 内 嵌 汇 编 器 认 为 发 生 了 寄 存 器 冲 突. 用 其 他 寄 存 器 代 替 R0 存 放 参 数 x, 使 得 该 函 数 将 x 原 封 不 动 地 返 回. 这 段 代 码 的 正 确 写 法 如 下 : int bad_f(intx) { asm { ADD x,x,#1 } 第 105 页
return(x) } 使 用 内 嵌 式 汇 编 无 需 保 存 和 恢 复 寄 存 器. 事 实 上, 除 了 CPSR 和 SPSR 寄 存 器, 对 物 理 寄 存 器 先 读 后 写 都 会 引 起 汇 编 器 报 错. 例 如.: int f(int x) { asm { STMFD SP!{R0} // 保 存 R0. 先 读 后 写, 汇 编 出 错 ADD EOR R0,x,1 x,r0,x LDMFD SP!,{R0} } returnt(x): } LDM 和 STM 指 令 的 寄 存 器 列 表 中 只 允 许 使 用 物 理 寄 存 器. 内 嵌 汇 编 可 以 修 改 处 理 器 模 式, 协 处 理 器 模 式 和 FP,SL,SB 等 APCS 寄 存 器. 但 是 编 译 器 在 编 译 时 并 不 了 解 这 些 变 化, 所 以 必 须 保 证 在 执 行 C 代 码 前 恢 复 相 应 被 修 改 的 处 理 器 模 式. 汇 编 语 言 中 的. 号 作 为 操 作 数 分 隔 符 号. 如 果 有 C 表 达 式 作 为 操 作 数, 若 表 达 式 包 含 有. 必 须 使 用 ( 号 和 ) 号 将 其 归 纳 为 一 个 汇 编 操 作 数 例 如 : _asm { ADD x,y,(f(),z) // f(),z 为 一 个 带 有. 的 C 表 达 式 } 访 问 全 局 变 量 使 用 IMPORT 伪 指 令 引 入 全 局 变 量, 并 利 用 LDR 和 STR 指 令 根 据 全 局 变 量 的 地 址 访 问 它 们, 对 于 不 同 类 型 的 变 量, 需 要 采 用 不 同 选 项 的 LDR 和 STR 指 令 : unsigned char unsigned short LDRB/STRB LDRH/STRH 第 106 页
unsingned int char short LDR/STR LDRSB/STRSB LDRSH/STRSH 对 于 结 构, 如 果 知 道 各 个 数 据 项 的 偏 移 量, 可 以 通 过 存 储 / 加 载 指 令 访 问. 如 果 结 构 所 占 空 间 小 于 8 个 字, 可 以 使 用 LDM 和 STM 一 次 性 读 写. 下 面 例 子 是 一 个 汇 编 代 码 的 函 数, 它 读 取 全 局 变 量 globval, 将 其 加 1 后 写 回. 访 问 C 程 序 的 全 局 变 量 : AREA globats,code,readonly] EXPORT asmsubroutime IMPORt glovbvar ; 声 明 外 部 变 量 glovbvar asmsubroutime LDR R1,=glovbvar ; 装 载 变 量 地 址 LDR R0,[R1] ; 读 出 数 据 ADD R0,R0,#1 ; 加 1 操 作 STR R0,[R1] ; 保 存 变 量 值 MOV PC LR END C 与 汇 编 相 互 调 用 在 C 程 序 和 ARM 汇 编 程 序 之 间 相 互 调 用 必 须 遵 守 ATPCS. 使 用 ADS 的 C 语 言 编 译 器 编 译 的 C 语 言 子 程 序 满 足 用 户 指 定 的 ATPCS 类 型. 而 对 于 汇 编 语 言 来 说, 完 全 要 依 赖 用 户 来 保 证 各 个 子 程 序 满 足 选 定 的 ATPCS 类 型. 具 体 来 说, 汇 编 语 言 子 程 序 必 须 满 足 下 面 3 个 条 件 : 在 子 程 序 编 写 时 必 须 遵 守 相 应 的 ATPCS 规 则 堆 栈 的 使 用 要 遵 守 相 应 的 ATPCS 规 则. 在 汇 编 编 译 器 中 使 用 -apcs 选 项 基 本 ATPCS 规 定 了 在 子 程 序 调 用 时 的 一 些 基 本 规 则, 包 括 : 各 寄 存 器 的 使 用 规 则 及 其 相 应 的 名 称, 堆 栈 的 使 用 规 则, 参 数 传 送 的 规 则. 第 107 页
寄 存 器 的 使 用 规 则 子 程 序 间 通 过 寄 存 器 R0~R3 来 传 递 参 数. 这 时, 寄 存 器 R0~R3 可 记 作 A0~A3. 被 调 用 的 子 程 序 在 返 回 前 无 须 恢 复 寄 存 器 R0~R3 的 内 容. 在 子 程 序 中, 使 用 寄 存 器 R4~R11 来 保 存 局 部 变 量. 这 时, 寄 存 器 R4~R11 可 以 记 作 V1~V8. 如 果 在 子 程 序 中 使 用 了 寄 存 器 V1~V8 中 的 某 些 寄 存 器, 子 程 序 进 入 时 必 须 保 存 这 些 寄 存 器 的 值, 在 返 回 前 必 须 恢 复 这 些 寄 存 器 的 值. 在 Thumb 程 序 中, 通 常 只 能 使 用 寄 存 器 R4~R7 来 保 存 局 部 变 量. 寄 存 器 R12 用 作 过 程 调 用 中 间 临 时 寄 存 器, 记 作 IP. 在 子 程 序 间 的 连 接 代 码 段 中 常 有 这 种 使 用 规 则. 寄 存 器 R13 用 作 堆 栈 指 针, 记 作 SP. 在 子 程 序 中 寄 存 器 R13 不 能 作 其 他 用 途. 寄 存 器 SP 在 进 入 子 程 序 时 的 值 和 退 出 子 程 序 时 的 值 必 须 相 等. 寄 存 器 R14 称 为 连 接 寄 存 器, 记 作 LR. 它 用 于 保 存 子 程 序 的 返 回 地 址. 如 果 在 子 程 序 中 保 存 了 返 回 地 址, 寄 存 器 R14 则 可 以 用 作 其 他 用 途. 寄 存 器 R15 是 程 序 计 数 器, 记 作 PC. 它 不 能 用 作 其 它 用 途. 堆 栈 使 用 规 则 ATPCS 规 定 堆 栈 为 FD 类 型, 即 满 递 减 堆 栈, 并 且 对 堆 栈 的 操 作 是 8 字 节 对 齐. 使 用 ADS 中 的 编 译 器 产 生 的 目 标 代 码 中 包 含 了 DRAFT2 格 式 的 数 据 帧. 在 调 试 过 程 中, 调 试 器 可 以 使 用 这 些 数 据 帧 来 查 看 堆 栈 中 的 相 关 信 息. 对 于 汇 编 语 言 来 说, 用 户 必 须 使 用 FRAME 伪 指 令 来 描 述 堆 栈 的 数 据 帧.ARM 汇 编 器 根 据 这 些 伪 指 令 在 目 标 文 件 中 产 生 相 应 的 DRAFT2 格 式 的 数 据 帧.( 堆 栈 中 的 数 据 帧 --- 在 堆 栈 中, 为 子 程 序 分 配 的 用 来 保 存 寄 存 器 和 局 部 变 量 的 区 域 ). 对 于 汇 编 程 序 来 说, 如 果 目 标 文 件 中 包 含 了 外 部 调 用, 则 必 须 满 足 下 列 条 件 : 外 部 接 口 的 堆 栈 必 须 是 8 字 节 对 齐 的. 在 汇 编 程 序 中 使 用 PRESERVE8 伪 指 令 告 诉 连 接 器, 本 汇 编 程 序 数 据 是 8 字 节 对 齐 的. 第 108 页
参 数 传 递 规 则 根 据 参 数 个 数 是 否 固 定 可 以 将 子 程 序 分 为 参 数 个 数 固 定 的 子 程 序 和 参 数 个 数 可 变 化 的 子 程 序. 这 两 种 子 的 参 数 传 递 规 则 是 不 一 样 的. 参 数 个 数 可 变 的 子 程 序 参 数 传 递 规 则 对 于 参 数 个 数 可 变 的 子 程 序, 当 参 数 不 超 过 4 个 时, 可 以 使 用 寄 存 器 R0~R3 来 传 递 参 数 ; 当 参 数 超 过 4 个 时, 还 可 以 使 用 堆 栈 来 传 递 参 数. 在 参 数 传 递 时, 将 所 有 参 数 看 作 是 存 放 在 连 续 的 内 存 字 单 元 的 字 数 据. 然 后, 依 次 将 各 字 数 据 传 送 到 寄 存 器 R0,R1,R2,R3 中, 如 果 参 数 多 于 4 个, 将 剩 余 的 字 数 据 传 送 堆 栈 中, 入 栈 的 顺 序 与 参 数 顺 序 相 反, 即 最 后 一 个 字 数 据 先 入 栈. 按 照 上 面 的 规 则, 一 个 浮 点 数 参 数 可 以 通 过 寄 存 器 传 递, 也 可 以 通 过 堆 栈 传 递, 也 可 能 一 半 通 过 寄 存 器 传 递, 另 一 半 通 过 堆 栈 传 递. 参 数 个 数 固 定 的 子 程 序 参 数 传 递 规 则 对 于 参 数 个 数 固 定 的 子 程 序, 参 数 传 递 与 参 数 个 数 可 变 的 子 程 序 参 数 传 递 规 则 不 同. 如 果 系 统 包 含 浮 点 运 算 的 硬 件 部 件, 浮 点 参 数 将 按 下 面 的 规 则 传 递 ; 各 个 浮 点 参 数 按 顺 序 处 理 ; 为 每 个 浮 点 参 数 分 配 FP 寄 存 器 ; 分 配 的 方 法 是, 满 足 该 浮 点 参 数 需 要 的 且 编 号 最 小 的 一 组 连 续 的 FP 寄 存 器 第 一 个 整 数 参 数, 通 过 寄 存 器 R0~R3 来 传 递. 其 他 参 数 通 过 堆 栈 传 递. 子 程 序 结 果 返 回 规 则 子 程 序 中 结 果 返 回 的 规 则 如 下 ; 结 果 为 一 个 32 位 的 整 数 时, 可 以 通 过 寄 存 器 R0 返 回 ; 结 果 为 一 个 64 位 的 整 数 时, 可 以 通 过 寄 存 器 R0 和 R1 返 回 ; 结 果 为 一 个 浮 点 数 时, 可 以 通 过 浮 点 运 算 部 件 的 寄 存 器 f0,d0 或 s0 来 返 回 ; 结 果 为 复 合 型 的 浮 点 ( 如 复 数 ) 时, 可 以 通 过 寄 存 器 f0~fna 或 d0~dn 来 返 回 ; 对 于 位 数 更 多 的 结 果, 需 要 通 过 内 存 来 传 递. 第 109 页
C 程 序 调 用 汇 编 程 序 汇 编 程 序 的 设 置 要 遵 循 ATPCS 规 则, 保 证 程 序 调 用 时 参 数 的 正 确 传 递. 在 汇 编 程 序 中 使 用 EXPORT 伪 指 令 声 明 本 子 程 序, 使 其 它 程 序 可 以 调 用 此 子 程 序. 在 C 语 言 程 序 中 使 用 extern 关 键 字 声 明 外 部 函 数 ( 声 明 要 调 用 的 汇 编 子 程 序 ), 即 可 调 用 此 汇 编 子 程 序. 如 以 下 程 序 所 示, 汇 编 子 程 序 strcopy 使 用 两 个 参 数, 一 个 表 示 目 标 字 符 串 地 址, 一 个 表 示 源 字 符 串 的 地 址, 参 数 分 别 存 放 R0,R1 寄 存 器 中. 调 用 汇 编 的 C 函 数 : #include <stdio.h> extern void strcopy(char*d,const char*s) // 声 明 外 部 函 数, 即 要 调 用 的 汇 编 子 程 序 int mian(void) { const char *srcstr= First string-source ; // 定 义 字 符 串 常 量 char dstsrt[] = Second string-destination ;// 定 义 字 符 串 变 量 printf( Before copying:\n ); printf( %s \n %s\n, srcstr,dststr); // 显 示 源 字 符 串 和 目 标 字 符 串 的 内 容 strcopy(dststr,srcstr); // 调 用 汇 编 子 程 序,R0=dststr,R1=srcstr printf( After copying:\n ) printf( %s \n %s\n, srcstr,dststr); // 显 示 strcopy 复 制 字 符 串 结 果 return(0); } 被 调 用 汇 编 子 程 序 : AREA EXPORT SCopy,CODE,READONLY strcopy ; 声 明 strcopy, 以 便 外 部 程 序 引 用 strcopy ;R0 为 目 标 字 符 串 的 地 址 ;R1 为 源 字 符 串 的 地 址 ; 第 110 页
LDRB R2,[R1],#1 ; 读 取 字 节 数 据, 源 地 址 加 1 STRB R2,[R0],#1 ; 保 存 读 取 的 1 字 节 数 据, 目 标 地 址 加 1 CMP r2,#0 ; 判 断 字 符 串 是 否 复 制 完 毕 BNE strcopy ; 没 有 复 制 完 毕, 继 续 循 环 MOV pc,lr ; 返 回 END 汇 编 程 序 调 用 C 程 序 汇 编 程 序 的 设 置 要 遵 循 ATPCS 规 则, 保 证 程 序 调 用 时 参 数 的 正 确 传 递. 在 汇 编 程 序 中 使 用 IMPORT 伪 指 令 声 明 将 要 调 用 的 C 程 序 函 数. 在 调 用 C 程 序 时, 要 正 确 设 置 入 口 参 数, 然 后 使 用 BL 调 用. 以 下 程 序 清 单 所 示, 程 序 使 用 了 5 个 参 数, 分 别 使 用 寄 存 器 R0 存 储 第 1 个 参 数,R1 存 储 第 2 个 数,R2 存 储 第 3 个 参 数,R3 存 储 第 4 个 参 数, 第 5 个 参 数 利 用 堆 栈 传 送. 由 于 利 用 了 堆 栈 传 递 参 数, 在 程 序 调 用 用 结 果 后 要 调 整 堆 栈 指 针 汇 编 调 用 C 程 序 的 C 函 数 : /* 函 数 sum5() 返 回 5 个 整 数 的 和 */ int sum5(int a,lit b, int c,int d,int e) { return(a+b+c+d+e); // 返 回 5 个 变 量 的 和 } 汇 编 调 用 C 程 序 的 汇 编 程 序 : EXPORT AREA CALLSUM5 Example, CODE,READONLY IMPORT sum5 ; 声 明 外 部 标 号 sum5, 即 C 函 数 sum5() CALLSUMS STMFD SP!{LR} ;LR 寄 存 器 放 栈 ADD R1,R0,R0 ; 设 置 sum5 函 数 入 口 参 数,R0 为 参 数 a ADD R2,R1,R0 ;R1 为 参 数 b,r2 为 参 数 c ADD R3,R1,R2, 第 111 页
STR R3,[SP,#-4]! ; 参 数 e 要 通 过 堆 栈 传 递 ADD R3,R1,R1 ;R3 为 参 数 d BL sum5 ; 调 用 sum5(), 结 果 保 存 在 R0 ADD SP,SP#4 ; 修 正 SP 指 针 LDMFD SP,{PC ; 子 程 序 返 回 END 第 112 页
ARM 指 令 集 列 表 ARM 存 储 器 访 问 指 令 表 列 表 助 记 符 说 明 操 作 条 件 码 位 置 LDR Rd,addressing 加 载 字 数 据 Rd [addressing],addressing 索 引 LDR{cond} LDRB Rd,addressing 加 载 无 符 字 节 数 据 Rd [addressing],addressing 索 引 LDR{cond}B LDRT Rd,addressing 以 用 户 模 式 加 载 字 数 据 Rd [addressing],addressing 索 引 LDR{cond}T LDRBT Rd,addressing 以 用 户 模 式 加 载 无 符 号 字 数 据 Rd [addressing],addressing 索 引 LDR{cond}BT LDRH Rd,addressing 加 载 无 符 半 字 数 据 Rd [addressing],addressing 索 引 LDR{cond}H LDRSB Rd,addressing 加 载 有 符 字 节 数 据 Rd [addressing],addressing 索 引 LDR{cond}SB LDRSH Rd,addressing 加 载 有 符 半 字 数 据 Rd [addressing],addressing 索 引 LDR{cond}SH STR Rd,addressing 存 储 字 数 据 [addressing] Rd,addressing 索 引 STR{cond} STRB Rd,addressing 存 储 字 节 数 据 [addressing] Rd,addressing 索 引 STR{cond}B STRT Rd,addressing 以 用 户 模 式 存 储 字 数 据 [addressing] Rd,addressing 索 引 STR{cond}T STRBT Rd,addressing 以 用 户 模 式 存 储 字 节 数 据 [addressing] Rd,addressing 索 引 STR{cond}BT STRH Rd,addressing 存 储 半 字 数 据 [addressing] Rd,addressing 索 引 STR{cond}H LDM{mode} Rn{!},reglist 批 量 ( 寄 存 器 ) 加 载 reglist [Rn],Rn 回 存 等 LDM{cond}{more} STM{mode} Rn{!},rtglist 批 量 ( 寄 存 器 ) 存 储 [Rn] reglist,rn 回 存 等 STM{cond}{more} SWP Rd,Rm,Rn 寄 存 器 和 存 储 器 字 数 据 交 换 Rd [Rd],[Rn] [Rm](Rn Rd 或 Rm) SWP{cond} SWPB Rd,Rm,Rn 寄 存 器 和 存 储 器 字 节 数 据 交 换 Rd [Rd],[Rn] [Rm](Rn Rd 或 Rm) SWP{cond}B 第 113 页
ARM 数 据 处 理 指 令 列 表 助 记 符 号 说 明 操 作 条 件 码 位 置 MOV Rd,operand2 数 据 转 送 Rd operand2 MOV {cond}{s} MVN Rd,operand2 数 据 非 转 送 Rd (operand2) MVN {cond}{s} ADD Rd,Rn operand2 加 法 运 算 指 令 Rd Rn+operand2 ADD {cond}{s} SUB Rd,Rn operand2 减 法 运 算 指 令 Rd Rn-operand2 SUB {cond}{s} RSB Rd,Rn operand2 逆 向 减 法 指 令 Rd operand2-rn RSB {cond}{s} ADC Rd,Rn operand2 带 进 位 加 法 Rd Rn+operand2+carry ADC {cond}{s} SBC Rd,Rn operand2 带 进 位 减 法 指 令 Rd Rn-operand2-(NOT)Carry SBC {cond}{s} RSC Rd,Rn operand2 带 进 位 逆 向 减 法 指 令 Rd operand2-rn-(not)carry RSC {cond}{s} AND Rd,Rn operand2 逻 辑 与 操 作 指 令 Rd Rn&operand2 AND {cond}{s} ORR Rd,Rn operand2 逻 辑 或 操 作 指 令 Rd Rn operand2 ORR {cond}{s} EOR Rd,Rn operand2 逻 辑 异 或 操 作 指 令 Rd Rn^operand2 EOR {cond}{s} BIC Rd,Rn operand2 位 清 除 指 令 Rd Rn&(~operand2) BIC {cond}{s} CMP Rn,operand2 比 较 指 令 标 志 N Z C V Rn-operand2 CMP {cond} CMN Rn,operand2 负 数 比 较 指 令 标 志 N Z C V Rn+operand2 CMN {cond} TST Rn,operand2 位 测 试 指 令 标 志 N Z C V Rn&operand2 TST {cond} TEQ Rn,operand2 相 等 测 试 指 令 标 志 N Z C V Rn^operand2 TEQ {cond} 第 114 页
ARM 乘 法 指 令 列 表 助 记 符 说 明 操 作 条 件 码 位 置 MUL Rd,Rm,Rs 32 位 乘 法 指 令 Rd Rm*Rs (Rd Rm) MUL{cond}{S} MLA Rd,Rm,Rs,Rn 32 位 乘 加 指 令 Rd Rm*Rs+Rn (Rd Rm) MLA{cond}{S} UMULL RdLo,RdHi,Rm,Rs 64 位 无 符 号 乘 法 指 令 (RdLo,RdHi) Rm*Rs UMULL{cond}{S} UMLAL RdLo,RdHi,Rm,Rs 64 位 无 符 号 乘 加 指 令 (RdLo,RdHi) Rm*Rs+(RdLo,RdHi) UMLAL{cond}{S} SMULL RdLo,RdHi,Rm,Rs 64 位 有 符 号 乘 法 指 令 (RdLo,RdHi) Rm*Rs SMULL{cond}{S} SMLAL RdLo,RdHi,Rm,Rs 64 位 有 符 号 乘 加 指 令 (RdLo,RdHi) Rm*Rs+(RdLo,RdHi) SMLAL{cond}{S} 第 115 页
ARM 跳 转 指 令 列 表 助 记 符 说 明 操 作 条 件 码 位 置 B label 跳 转 指 令 Pc label B{cond} BL label 带 链 接 的 跳 转 指 令 LR PC-4, PC label BL{cond} BX Rm 带 状 态 切 换 的 跳 转 指 令 PC label, 切 换 处 理 状 态 BX{cond} 第 116 页
ARM 协 处 理 器 指 令 列 表 助 记 符 说 明 操 作 条 件 码 位 置 CDP coproc,opcodel,crd,crn,crm{,opcode2} 协 处 理 器 数 据 操 作 指 令 取 决 于 协 处 理 器 CDP{cond} LDC{L} coproc,crd 地 址 协 处 理 器 数 据 读 取 指 令 取 决 于 协 处 理 器 LDC{cond}{L} STC{L} coproc,crd, 地 址 协 处 理 器 数 据 写 入 指 令 取 决 于 协 处 理 器 STC{cond}{L} MCR coproc, opcodel,rd,crn,{,opcode2} ARM 寄 存 器 到 协 处 理 器 寄 存 器 的 数 据 传 送 指 令 取 决 于 协 处 理 器 MCR{cond} MRC coproc, opcodel,rd,crn,{,opcode2} 协 处 理 器 寄 存 器 到 ARM 寄 存 器 到 数 据 传 送 指 令 取 决 于 协 处 理 器 MCR{cond} 第 117 页
ARM 杂 项 指 令 列 表 助 记 符 说 明 操 作 条 件 码 位 置 SWI immed_24 软 中 断 指 令 产 生 软 中 断, 处 理 器 进 入 管 理 模 式 SWI{cond} MRS Rd,psr 读 状 态 寄 存 器 指 令 Rd psr,psr 为 CPSR 或 SPSR MRS{cond} MSR psr_fields,rd/#immed_8r 写 状 态 寄 存 器 指 令 psr_fields Rd/#immed_8r,psr 为 CPSR 或 SPSR MSR{cond} 第 118 页
ARM 伪 指 令 列 表 伪 指 令 助 记 符 说 明 操 作 条 件 码 位 置 ADR register,expr 小 范 围 的 地 址 读 取 伪 指 令 register<-expr 指 向 的 地 址 ADR{cond} ADRL register,expr 中 等 范 围 的 地 址 读 取 伪 指 令 register<-expr 指 向 的 地 址 ADR{cond} LDR 大 范 围 的 地 址 读 取 伪 指 令 register<-expr/label-expr 指 定 LDR{cond} register,=expr/label-expr 的 数 据 / 地 址 NOP 空 操 作 伪 指 令 无 无 第 119 页
Thumb 指 令 集 列 表 Thumb 存 储 器 访 问 指 令 列 表 助 记 符 说 明 操 作 影 响 标 志 LDR Rd,[Rn,#immed_5 4] 加 载 字 数 据 Rd [Rm,#immed_5 4],Rd,Rn 为 R0~R7 无 LDRH Rd,[Rn,#immed_5 2] 加 载 无 符 半 字 数 据 Rd [Rm,#immed_5 2],Rd,Rn 为 R0~R7 无 LDRB Rd,[Rn,#immed_5 1] 加 载 无 符 字 节 数 据 Rd [Rm,#immed_5 1],Rd,Rn 为 R0~R7 无 STR Rd,[Rn,#immed_5 4] 存 储 字 数 据 Rn,#immed_5 4Rd Rd,Rn 为 R0~R7 无 STRH Rd,[Rn,#immed_5 2] 存 储 无 符 半 辽 数 据 Rn,#immed_5 2]Rd Rd,Rn 为 R0~R7 无 STRB Rd,[Rn#immed_5 1] 存 储 无 符 字 节 数 据 Rn,#immed_5 1]Rd Rd,Rn 为 R0~R7 无 LDR Rd,[Rn,Rm] 加 载 字 数 据 Rd [Rn,Rm],Rd,Rn,Rm 为 R0~R7 无 LDRH Rd,[Rn,Rm] 加 载 无 符 半 字 数 据 Rd [Rn,Rm],Rd,Rn,Rm 为 R0~R7 无 LDRB Rd,[Rn,Rm] 加 载 无 符 字 节 数 据 Rd [Rn,Rm],Rd,Rn,Rm 为 R0~R7 无 LDRSH Rd[Rn,Rm] 加 载 有 符 半 字 数 据 Rd [Rn,Rm],Rd,Rn,Rm 为 R0~R7 无 LDRSB Rd[Rn,Rm] 加 载 有 符 字 节 数 据 Rd [Rn,Rm],Rd,Rn,Rm 为 R0~R7 无 STR Rd,[Rn,Rm] 存 储 字 数 据 [Rn,Rm] Rd,Rd,Rn,Rm 为 R0~R7 无 STRH Rd,[Rn,Rm] 存 储 无 符 半 字 数 据 [Rn,Rm] Rd,Rd,Rn,Rm 为 R0~R7 无 STRB Rd,[Rn,Rm] 存 储 无 符 字 节 数 据 [Rn,Rm] Rd,Rd,Rn,Rm 为 R0~R7 无 LDR Rd,[PC,#immed_8 4] 基 于 PC 加 载 字 数 据 Rd {PC,#immed_8 4]Rd 为 R0~R7 无 LDR Rd,label 基 于 PC 加 载 字 数 据 Rd [label],rd 为 R0~R7 无 LDR Rd,[SP,#immed_8 4] 基 于 SP 加 载 字 数 据 Rd {SP,#immed_8 4]Rd 为 R0~R7 无 STR Rd,[SP,#immed_8 4] 基 于 SP 存 储 字 数 据 {SP,#immed_8 4] Rd,Rd 为 R0~R7 无 LDMIA Rn{!}reglist 批 量 ( 寄 存 器 ) 加 载 regist [Rn],Rn 回 存 等 (R0~R7) 无 STMIA Rn{!}reglist 批 量 ( 寄 存 器 ) 加 载 [Rn] reglist,rn 回 存 等 (R0~R7) 无 PUSH {reglist[,lr]} 寄 存 器 入 栈 指 令 [SP] reglist[,lr],sp 回 存 等 (R0~R7,LR) 无 POP {reglist[,pc]} 寄 存 器 入 栈 指 令 reglist[,pc] [SP],SP 回 存 等 (R0~R7,PC) 无 第 120 页
Thumb 数 据 处 理 指 令 列 表 助 记 符 说 明 操 作 影 响 标 志 MOV Rd,#expr 数 据 转 送 Rd expr,rd 为 R0~R7 影 响 N,Z MOV Rd,Rm 数 据 转 送 Rd Rm,Rd Rm 均 可 为 R0~R15 RdT 和 Rm 均 为 R0~R7 时, 影 响 N,Z, 清 零 C,V MVN Rd,Rm 数 据 非 传 送 指 令 Rd (~Rm),Rd,Rm 均 为 R0~R7 影 响 N,Z NEG Rd,Rm 数 据 取 负 指 令 Rd (-Rm),Rd,Rm 均 为 R0~R7 影 响 N,Z,C,V ADD Rd.Rn,Rm 加 法 运 算 指 令 Rd Rn+Rm,Rd,Rn,Rm 均 为 R0~R7 影 响 N,Z,C,V ADD Rd.Rn,#expr3 加 法 运 算 指 令 Rd Rn+expr#,Rd,Rn 均 为 R0~R7 影 响 N,Z,C,V ADD Rd,#expr8 加 法 运 算 指 令 Rd Rd+expr8,Rd 为 R0~R7 影 响 N,Z,C,V ADD Rd,Rm 加 法 运 算 指 令 Rd Rd+Rm,Rd,Rm 均 可 为 R0~R15 Rd 和 Rm 均 为 R0~R7 时, 影 响 N,Z,C,V ADD Rd,Rp#expr SP/PC 加 法 运 算 指 令 Rd SP+expr 或 PC+expr,Rd 为 R0~R7 无 ADD SP,#expr SP 加 法 运 算 指 令 SP SP+expr 无 SUB Rd,Rn,Rm 减 法 运 算 指 令 Rd Rn-Rm,Rd Rn Rm 均 为 R0~R7 影 响 N,Z,C,V SUB Rd,Rn,#expr3 减 法 运 算 指 令 Rd Rn-expr3,RdRn 均 为 R0~R7 影 响 N,Z,C,V SUB Rd,#expr8 减 法 运 算 指 令 RD Rd-expr8,Rd 为 R0~R7 影 响 N,Z,C,V SUB SP,#expr SP 减 法 运 算 指 令 SP SP-expr 无 ADC Rd,Rm 带 进 位 加 法 指 令 Rd Rd+Rm+Carry,Rd Rm 为 R0~R7 影 响 N,Z,C,V SBC Rd,Rm 带 位 减 法 指 令 Rd Rd-Rm-(NOT)Carry,Rd Rm 为 R0~R7 影 响 N,Z,C,V MUL Rd,Rm 乘 法 运 算 指 令 Rd Rd*Rm,Rd Rm 为 R0~R7 影 响 N,Z, AND Rd,Rm 逻 辑 与 操 作 指 令 Rd Rd&Rm,Rd Rm 为 R0~R7 影 响 N,Z, ORR Rd,Rm 逻 辑 或 操 作 指 令 Rd Rd Rm,Rd Rm 为 R0~R7 影 响 N,Z, EOR Rd,Rm 逻 辑 异 或 操 作 指 令 Rd Rd^Rm,Rd Rm 为 R0~R7 影 响 N,Z, BIC Rd,Rm 位 清 除 指 令 Rd Rd&(~Rm),Rd Rm 为 R0~R7 影 响 N,Z, ASR Rd,Rs 算 术 右 移 指 令 Rd Rd 算 术 右 移 Rs 位,Rd,Rs 为 R0~R7 影 响 N,Z,C, ASR Rd,Rm,#expr 算 术 右 移 指 令 Rd Rm 算 术 右 移 expr 位,Rd Rm 为 R0~R7 影 响 N,Z,C, LSL Rd,Rs 逻 辑 左 移 指 令 Rd Rd<<Rs,Rd Rs 为 R0~R7 影 响 N,Z,C, LSL Rd,Rm,#expr 逻 辑 左 移 指 令 Rd Rm<<expr,Rd Rm 为 R0~R7 影 响 N,Z,C, LSR Rd,Rs 逻 辑 右 移 指 令 Rd Rd>>Rs,Rd Rs 为 R0~R7 影 响 N,Z,C, LSR Rd,Rm,#expr 逻 辑 右 移 指 令 Rd Rm>>mexpr,Rd Rm 为 R0~R7 影 响 N,Z,C, ROR Rd,Rs 循 环 右 移 指 令 Rd Rm 循 环 右 移 Rs 位,Rd Rs 为 R0~R7 影 响 N,Z,C, CMP Rn,Rm 比 较 指 令 状 态 标 Rn-Rm,Rn Rm 为 R0~R15 影 响 N,Z,C,V CMP Rn,#expr 比 较 指 令 状 态 标 Rn-expr,Rn 为 R0~R7 影 响 N,Z,C,V CMN Rn,Rm 负 数 比 较 指 令 ] 状 态 标 Rn+Rm,Rn Rm 为 R0~R7 影 响 N,Z,C,V TST Rn,Rm 位 测 试 指 令 状 态 标 Rn&Rm,Rn Rm 为 R0~R7 影 响 N,Z,C,V 第 121 页
Thumb 跳 转 指 令 及 软 中 断 指 令 列 表 助 记 符 说 明 操 作 条 件 码 位 置 B label 跳 转 指 令 PC label B{cond} BL label 带 链 接 的 跳 转 指 令 LR PC 4,PC label 无 BX Rm 带 状 态 切 换 的 跳 转 指 令 PC label 切 换 处 理 器 状 态 无 SWI immed_8 软 中 断 指 令 产 生 软 中 断, 处 理 器 进 入 管 理 模 式 无 第 122 页
Thumb 伪 指 令 列 表 伪 指 令 助 记 符 说 明 操 作 条 件 码 位 置 ADR register,expr 小 范 围 的 地 址 读 取 伪 指 令 register<-expr 指 向 的 地 址 无 LDR register<-expr/label-expr 指 大 范 围 的 地 址 读 取 伪 指 令 register,=expr/label-expr 定 的 数 据 / 地 址 无 NOP 空 操 作 伪 指 令 无 无 第 123 页
汇 编 预 定 义 变 量 及 伪 指 令 预 定 义 的 寄 存 器 和 协 处 理 器 名 ARM 汇 编 器 对 ARM 的 寄 存 器 进 行 了 预 定 义 ( 包 括 APCS 对 R0~R15 寄 存 器 的 定 义 ), 所 有 的 寄 存 器 和 协 处 理 器 名 都 是 大 小 写 敏 感. 预 定 义 的 寄 存 器 如 下 : 通 用 寄 存 器 R0~R15 和 r0~r15 (16 个 通 用 寄 存 器 ); a1~a4( 参 数, 结 果 或 临 时 寄 存 器, 同 R0~R3); v1~v8( 变 量 寄 存 器, 同 R4~R11); SB 和 sb( 静 态 基 址, 同 R9); SL 和 sl( 堆 栈 限 制, 同 R10); FP 和 fp( 帧 指 针 ); IP 和 ip( 过 程 调 用 中 间 临 时 寄 存 器, 同 R12); SP 和 sp( 堆 栈 指 针, 同 R13); LR 和 lr( 链 接 寄 存 器, 同 R14); PC 和 pc( 程 序 计 数 器, 同 R15). 程 序 状 态 寄 存 器 CPSR 和 cpsr; SPSR 和 spsr; 浮 点 数 寄 存 器 F0~F7 和 f0~f7(fpa 寄 存 器 ); S0~S7 和 s0~s7(vfp 单 精 度 寄 存 器 ); D0~D7 和 d0~d7(vfp 双 精 度 寄 存 器 ); 第 124 页
协 处 理 器 及 协 处 理 器 寄 存 器 p0~p15( 协 处 理 器 0~15); c0~c15( 协 处 理 器 寄 存 器 0~15); 内 置 变 量 列 表 ARM 汇 编 器 中 定 义 了 一 些 内 置 变 量, 如 下 表 所 示. 这 些 内 置 变 量 不 能 使 用 伪 指 令 设 置 ( 如 SETA,SETL,SETS), 一 般 用 于 程 序 的 条 件 汇 编 控 制 等, 如 下 ; IF {CONFIG}=16 ELSE ENDIF B ; 跳 转 到 当 前 地 址, 即 死 循 环 内 置 变 量 表 变 量 说 明 {PC} 或 "." 当 前 指 令 的 地 址 {VAR} 或 "@" 存 储 区 位 置 计 数 器 的 当 前 值 {TRUE} 逻 辑 真 {FALSE} 逻 辑 假 {OPT} 当 前 设 置 列 表 选 项 值.OPT 用 来 保 存 当 前 列 表 选 项, 改 变 选 项 值, 或 恢 复 原 始 值 {CONFIG} 如 果 汇 编 器 汇 编 ARM 代 码, 则 值 为 32; 若 是 汇 编 Thumb 代 码, 则 值 为 16 {ENDLAN} 如 果 汇 编 器 在 大 端 模 式 下, 则 值 为 big; 若 在 小 端 模 式 下, 否 则 为 little {CODESIZE} 如 果 汇 编 Thumb 代 码, 则 值 为 16, 否 则 为 32. 同 {CONFIG} 变 量 {CPU} 选 定 的 CPU 名, 缺 省 为 ARM7TDMI. 如 果 用 命 令 行 -cpu 选 项, 则 为 genericarm {FPU} 设 定 的 FPU 名, 缺 省 为 SoftVFP {ARCHITECTURE} 选 定 的 ARM 体 系 结 构 的 值, 如 3,3M,4,4T,4TxM {PCSTOREOFFSET} STR pc,[] 或 STR Rb,{PC} 指 令 的 地 址 和 PC 的 存 储 值 之 间 的 偏 移 量 {ARMASM_VERSION} 或 ads$ version ARM ASM 的 版 本 号, 为 整 数 第 125 页
伪 指 令 列 表 伪 指 令 类 型 伪 指 令 功 能 符 号 定 义 指 示 符 数 据 定 义 指 示 符 报 告 指 示 符 GBLA 声 明 一 个 全 局 的 算 术 变 量, 并 将 其 初 始 化 为 0 GBLL 声 明 一 个 全 局 的 逻 辑 变 量, 并 将 其 初 始 化 为 {FALSE} GBLS 声 明 一 个 全 局 的 字 符 串 变 量, 并 将 其 初 始 化 为 空 字 符 串 "" LCLA 声 明 一 个 局 部 的 算 术 变 量, 并 将 其 初 始 化 为 0 LCLL 声 明 一 个 局 部 的 逻 辑 变 量, 并 将 其 初 始 化 为 {FALSE} LCLS 声 明 一 个 局 部 的 字 符 串 变 量, 并 将 其 初 始 化 为 空 字 符 串 "" SETA SETL SETS RLIST CN CP DN SN FN LTORG MAP 或 ^ FIELD 或 # SPACE 或 % DCB 或 = DCD 或 & 给 一 个 全 局 / 局 部 的 算 术 变 量 赋 值 给 一 个 全 局 / 局 部 的 逻 辑 变 量 赋 值 给 一 个 全 局 / 局 部 的 字 符 串 变 量 赋 值 为 一 个 通 用 寄 存 器 列 表 定 义 名 称 给 一 个 协 处 理 器 寄 存 器 命 名, 协 处 理 器 寄 存 器 编 号 为 0~15 为 一 个 协 处 理 器 定 义 名 称, 协 处 理 器 编 号 为 0~15 为 一 个 双 精 度 的 VFP 寄 存 器 定 义 名 称 为 一 个 单 精 度 的 VFP 寄 存 器 定 义 名 称 为 一 个 FPA 浮 点 寄 存 器 定 义 名 称 声 明 一 个 文 字 池 定 义 一 个 机 构 化 的 内 存 表 首 地 址 定 义 机 构 化 内 存 表 中 的 一 个 数 据 域 分 配 一 块 内 存 空 间, 并 用 0 初 始 化 分 配 一 段 字 节 的 内 存 单 元, 并 用 指 定 的 数 据 初 始 化 分 配 一 段 字 的 内 存 单 元, 并 用 指 定 的 数 据 初 始 化 DCDU 分 配 一 段 在 字 的 内 存 单 元, 并 用 指 定 的 数 据 初 始 化 ( 不 需 要 字 对 齐 ) DCDO DCFD 分 配 一 段 字 的 内 存 单 元, 将 每 个 单 元 的 内 容 初 始 化 为 该 单 元 相 对 于 静 态 基 地 址 寄 存 器 的 偏 移 量 分 配 一 段 双 字 的 内 存 单 元, 并 用 双 精 度 的 浮 点 数 初 始 化 DCFDU 分 配 一 段 双 字 的 内 存 单 元, 并 用 双 精 度 的 浮 点 数 据 初 始 化 ( 不 需 要 字 对 齐 ) DCFS 分 配 一 段 字 的 内 存 单 元, 并 用 单 精 度 的 浮 点 数 据 初 始 化 DCFSU 分 配 一 段 字 的 内 存 单 元, 并 用 单 精 度 的 浮 点 数 据 初 始 化 ( 不 需 要 字 对 齐 ) DCI DCQ 分 配 一 段 字 节 的 内 存 单 元, 用 指 定 的 数 据 初 始 化, 指 定 内 存 单 元 存 放 的 是 代 码 而 不 是 数 据 分 配 一 段 双 字 的 内 存 单 元, 并 用 64 位 的 整 数 数 据 初 始 化 DCQU 分 配 一 段 双 字 的 内 存 单 元, 并 用 64 位 的 整 数 数 据 初 始 化 ( 不 需 要 字 对 齐 ) DCW 分 配 一 段 半 字 的 内 存 单 元, 并 用 指 定 的 数 据 初 始 化 DCWU 分 配 一 段 半 字 的 内 存 单 元, 并 用 指 定 的 数 据 初 始 化 ( 不 需 要 字 对 齐 ) ASSERT INFO 或! OPT 在 汇 编 编 译 器 对 汇 编 程 序 的 第 二 遍 扫 描 中, 如 果 ASSERT 条 件 不 成 立,ASSERT 伪 指 令 将 报 告 该 错 误 信 息 在 汇 编 编 译 器 对 汇 编 程 序 的 第 一 遍 或 第 二 遍 扫 描 时 报 告 诊 断 信 息 在 源 程 序 中 设 置 列 表 选 项 第 126 页
汇 编 控 制 指 示 符 杂 项 指 示 符 ARM 伪 指 令 Thumb 伪 指 令 TTL SUBT IF 或 [ ELSE 或 ENDIF 或 ] MACRO MEND MEXIT WHILE WEND ALIGN AREA CODE16 CODE32 END ENTRY EQU 或 * EXPORT 或 GLOBAL IMPORT 或 EXTERN GET 或 INCLUDE INCBIN KEEP NOFP REQUIRE REQUIRE8 PRESERVE8 RN ROUT ADR ADRL LDR NOP ADR LDR NOP 在 列 表 文 件 中 的 每 一 页 的 开 头 插 入 一 个 标 题 在 列 表 文 件 中 的 每 一 页 的 开 头 插 入 一 个 子 标 题 IF ELSE 和 ENDIF 伪 指 令 能 够 根 据 条 件 把 一 段 源 代 码 包 括 在 汇 编 源 程 序 内 或 将 其 排 除 在 外 MACRO 和 MEND 伪 指 令 用 于 宏 定 义 退 出 宏 定 义 WHILE 和 WEND 伪 指 令 用 于 根 据 条 件 重 复 汇 编 相 同 的 或 几 乎 相 同 的 一 段 源 代 码 通 过 添 加 补 丁 字 节 使 当 前 位 置 满 足 一 定 的 对 齐 方 式 定 义 一 个 代 码 段 或 数 据 段 指 示 汇 编 编 译 器 后 面 的 指 令 为 16 位 的 Thumb 指 令 指 示 汇 编 编 译 器 后 面 的 指 令 为 32 位 的 ARM 指 令 指 示 汇 编 编 译 器 源 文 件 已 结 束 指 定 程 序 入 口 点 为 数 字 常 量 基 于 寄 存 器 的 值 和 程 序 中 的 标 号 定 义 一 个 名 称 声 明 一 个 符 号 可 以 被 其 它 文 件 引 用 相 当 于 生 命 了 一 个 全 局 变 量 指 示 编 译 器 当 前 的 符 号 不 是 在 本 源 文 件 中 定 义 的, 而 是 在 其 它 源 文 件 中 定 义 的, 在 本 源 文 件 中 可 能 引 用 该 符 号 将 一 个 源 文 件 包 含 到 当 前 源 文 件 中, 并 将 被 包 含 的 文 件 在 其 当 前 位 置 进 行 汇 编 处 理 将 一 个 文 件 包 含 到 当 前 源 文 件 中, 而 被 包 含 的 文 件 不 进 行 和 汇 编 处 理 指 示 编 译 器 保 留 符 号 表 中 的 局 部 符 号 禁 止 源 程 序 中 包 含 浮 点 运 算 指 令 指 定 段 之 间 的 依 赖 关 系 指 示 当 前 文 件 请 求 堆 栈 为 8 字 节 对 齐 指 示 当 前 文 件 保 持 堆 栈 为 8 字 节 对 齐 给 一 个 特 殊 的 寄 存 器 命 名 定 义 局 部 标 号 的 有 效 范 围 小 范 围 的 地 址 读 取 伪 指 令 中 等 范 围 的 地 址 读 取 伪 指 令 大 范 围 的 地 址 读 取 伪 指 令 空 操 作 伪 指 令 中 等 范 围 的 地 址 读 取 伪 指 令 大 范 围 的 地 址 读 取 伪 指 令 空 操 作 伪 指 令 第 127 页
指 令 条 件 码 列 表 条 件 码 助 记 符 标 志 含 义 EQ Z=1 相 等 NE Z=0 不 相 等 CS/HS C=1 无 符 号 数 大 于 或 等 于 CC/LO C=0 无 符 号 数 小 于 MI N=1 负 数 PL N=0 正 数 或 零 VS V=1 溢 出 VC V=0 没 有 溢 出 HI C=1,Z=0 无 符 号 数 大 于 LS C=0,Z=1 无 符 号 数 小 于 或 等 于 GE N=V 带 符 号 数 大 于 或 等 于 LT N!=V 带 符 号 数 小 于 GT Z=0,N=V 带 符 号 数 大 于 LE Z=1,N!=V 带 符 号 数 小 于 或 等 于 AL 任 何 无 条 件 执 行 ( 指 令 默 认 条 件 ) 第 128 页
CPSR 和 SPSR 分 配 图 CPSR 或 SPSR 模 式 常 量 定 义 : CPSR_f 或 SPSR_f CPSR_s 或 SPSR_s CPSR_x 或 SPSR_x CPSR_c 或 SPSR_c 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 N Z C V -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- I F T M4 M3 M2 M1 M0 负 数 或 小 于 零 进 位 或 借 位 或 扩 展 溢 出 保 留 位 IRQ 禁 止 1- 禁 止 0 允 许 FIQ 禁 止 1- 禁 止 0 允 许 状 态 位 0-ARM 1-Thumb 模 式 位 10000-0x0010- 用 户 10001-0x0011- 快 速 中 断 10010-0x0012- 中 断 10011-0x0013 管 理 10111-0x0017- 未 定 义 11111-0x001F- 系 统 第 129 页