01.12.2014 Views

RealView Compilation Tools Developer Guide - ARM Information ...

RealView Compilation Tools Developer Guide - ARM Information ...

RealView Compilation Tools Developer Guide - ARM Information ...

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

<strong>RealView</strong><br />

编 译 工 具<br />

2.0 版<br />

开 发 者 指 南<br />

© 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。<br />

<strong>ARM</strong> DUI 0203BSC


<strong>RealView</strong> 编 译 工 具<br />

开 发 者 指 南<br />

© 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。<br />

发 行 版 信 息<br />

已 对 本 书 做 出 了 下 列 更 改 。<br />

更 改 历 史<br />

日 期 问 题 更 改<br />

2002 年 8 月 A 发 行 版 1.2<br />

2003 年 1 月 B 发 行 版 2.0<br />

所 有 权 声 明<br />

带 有<br />

®<br />

或 标 记 的 单 词 和 徽 标 是 <strong>ARM</strong> Limited 所 拥 有 的 注 册 商 标 或 商 标 。 此 处 提 到 的 其 它 品 牌 和 名<br />

称 可 能 是 其 各 自 拥 有 者 的 商 标 。<br />

未 经 版 权 拥 有 者 的 事 先 书 面 允 许 , 不 得 以 任 何 材 料 形 式 改 编 或 复 制 本 文 档 所 含 信 息 或 所 述 产 品 的 部<br />

分 或 全 部 内 容 。<br />

本 文 档 中 描 述 的 产 品 可 能 会 进 行 不 断 的 开 发 和 改 进 。 本 产 品 的 所 有 细 节 以 及 本 文 档 中 包 含 的 其 用<br />

途 , 都 是 由 <strong>ARM</strong> 诚 意 提 供 的 。 但 是 , 我 们 将 不 做 出 所 有 隐 含 的 或 明 示 的 保 证 , 包 括 但 不 限 于 对 可<br />

销 售 性 或 适 合 特 定 用 途 的 保 证 。<br />

本 文 档 仅 旨 在 帮 助 读 者 使 用 本 产 品 。 <strong>ARM</strong> Limited 将 不 对 因 使 用 本 文 档 中 的 任 何 信 息 而 造 成 的 损 失<br />

或 损 害 负 责 , 也 不 对 这 些 信 息 中 的 任 何 错 误 或 遗 漏 或 对 本 产 品 的 任 何 不 正 确 使 用 负 责 。<br />

机 密 性 状 态<br />

本 文 档 是 供 开 放 访 问 的 。 对 其 没 有 传 播 限 制 。<br />

产 品 状 态<br />

本 文 档 中 的 信 息 是 最 终 信 息 ( 即 为 已 开 发 好 的 产 品 提 供 的 信 息 )。<br />

网 址<br />

http://www.arm.com<br />

ii © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


目 录<br />

<strong>RealView</strong> 编 译 工 具 汇 编 程 序 指 南<br />

序 言<br />

关 于 本 书 ..........................................................................................................vi<br />

反 馈 .................................................................................................................ix<br />

第 1 章<br />

第 2 章<br />

第 3 章<br />

简 介<br />

1.1 关 于 RVCT 开 发 者 指 南 ................................................................................1-2<br />

1.2 通 用 程 序 设 计 问 题 ........................................................................................1-5<br />

1.3 为 <strong>ARM</strong> 处 理 器 开 发 代 码 ............................................................................1-10<br />

嵌 入 式 软 件 开 发<br />

2.1 关 于 嵌 入 式 软 件 开 发 .....................................................................................2-2<br />

2.2 RVCT 在 目 标 未 知 情 况 下 的 缺 省 行 为 ...........................................................2-4<br />

2.3 调 整 C 库 使 其 适 应 目 标 硬 件 .......................................................................2-10<br />

2.4 调 整 映 象 存 储 器 映 射 以 适 应 目 标 硬 件 .........................................................2-13<br />

2.5 复 位 和 初 始 化 .............................................................................................2-23<br />

2.6 进 一 步 的 存 储 器 映 射 考 虑 事 项 ....................................................................2-33<br />

使 用 过 程 调 用 标 准<br />

3.1 关 于 <strong>ARM</strong>-Thumb 过 程 调 用 标 准 ..................................................................3-2<br />

3.2 寄 存 器 角 色 和 名 称 ........................................................................................3-4<br />

3.3 栈 .................................................................................................................3-6<br />

3.4 参 数 传 递 .......................................................................................................3-9<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 iii


3.5 栈 限 制 检 查 ................................................................................................. 3-11<br />

3.6 只 读 位 置 无 关 ............................................................................................. 3-14<br />

3.7 读 写 位 置 无 关 ............................................................................................. 3-15<br />

3.8 <strong>ARM</strong> 状 态 和 Thumb 状 态 之 间 的 交 互 操 作 ................................................. 3-16<br />

3.9 浮 点 选 项 .................................................................................................... 3-17<br />

第 4 章<br />

第 5 章<br />

第 6 章<br />

第 7 章<br />

<strong>ARM</strong> 和 Thumb 交 互 操 作<br />

4.1 关 于 交 互 操 作 ............................................................................................... 4-2<br />

4.2 汇 编 语 言 交 互 操 作 ........................................................................................ 4-5<br />

4.3 C 和 C++ 交 互 操 作 和 胶 合 代 码 .................................................................. 4-10<br />

4.4 使 用 胶 合 代 码 的 汇 编 语 言 交 互 操 作 ............................................................. 4-14<br />

混 合 使 用 C、 C++ 和 汇 编 语 言<br />

5.1 使 用 内 联 汇 编 程 序 ........................................................................................ 5-2<br />

5.2 使 用 嵌 入 式 汇 编 程 序 .................................................................................. 5-12<br />

5.3 内 联 汇 编 代 码 与 嵌 入 式 汇 编 代 码 之 间 的 差 异 .............................................. 5-15<br />

5.4 从 汇 编 代 码 访 问 C 全 局 变 量 ...................................................................... 5-16<br />

5.5 在 C++ 中 使 用 C 头 文 件 ............................................................................ 5-17<br />

5.6 C、 C++ 和 <strong>ARM</strong> 汇 编 语 言 之 间 的 调 用 ...................................................... 5-19<br />

处 理 处 理 器 异 常<br />

6.1 关 于 处 理 器 异 常 ........................................................................................... 6-2<br />

6.2 确 定 处 理 器 状 态 ........................................................................................... 6-5<br />

6.3 进 入 和 离 开 异 常 ........................................................................................... 6-7<br />

6.4 处 理 异 常 .................................................................................................... 6-12<br />

6.5 安 装 异 常 处 理 程 序 ...................................................................................... 6-13<br />

6.6 SWI 处 理 程 序 ............................................................................................ 6-18<br />

6.7 中 断 处 理 程 序 ............................................................................................. 6-27<br />

6.8 复 位 处 理 程 序 ............................................................................................. 6-36<br />

6.9 未 定 义 的 指 令 处 理 程 序 ............................................................................... 6-37<br />

6.10 预 取 中 断 处 理 程 序 ...................................................................................... 6-38<br />

6.11 数 据 中 断 处 理 程 序 ...................................................................................... 6-39<br />

6.12 链 结 异 常 处 理 程 序 ...................................................................................... 6-41<br />

6.13 系 统 模 式 ..................................................................................................... 6-43<br />

调 试 通 信 通 道<br />

7.1 关 于 调 试 通 信 通 道 ........................................................................................ 7-2<br />

7.2 目 标 数 据 传 送 ............................................................................................... 7-3<br />

7.3 轮 询 调 试 通 信 ............................................................................................... 7-4<br />

7.4 中 断 驱 动 调 试 通 信 ........................................................................................ 7-8<br />

7.5 从 Thumb 状 态 访 问 ..................................................................................... 7-9<br />

7.6 半 主 机 ........................................................................................................ 7-10<br />

词 汇 表<br />

iv © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


序 言<br />

本 序 言 介 绍 <strong>RealView</strong> 编 译 工 具 2.0 版 开 发 者 指 南 。 其 中 包 含 下 列 各 部 分 :<br />

• 第 vi 页 的 关 于 本 书 ;<br />

• 第 ix 页 的 反 馈 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 v


序 言<br />

关 于 本 书<br />

此 手 册 为 编 写 以 <strong>ARM</strong> 系 列 处 理 器 为 目 标 的 代 码 提 供 指 导 信 息 。<br />

适 合 的 读 者<br />

本 手 册 适 用 于 所 有 编 写 <strong>ARM</strong> 代 码 的 开 发 人 员 。 它 假 设 您 是 有 经 验 的 软 件 开 发<br />

人 员 , 并 且 熟 悉 <strong>RealView</strong> <strong>Compilation</strong> <strong>Tools</strong> v2.0 Getting Started <strong>Guide</strong> 中 描 述 的<br />

<strong>ARM</strong> 开 发 工 具 。<br />

使 用 本 书<br />

本 书 按 下 列 各 章 组 织 :<br />

第 1 章 简 介<br />

阅 读 此 章 , 了 解 <strong>RealView</strong> 编 译 工 具 的 简 介 (RVCT)。<br />

第 2 章 嵌 入 式 软 件 开 发<br />

阅 读 此 章 , 了 解 如 何 用 RVCT 开 发 嵌 入 式 应 用 程 序 的 详 细 信 息 。 它<br />

描 述 与 目 标 系 统 无 关 的 默 认 RVCT 行 为 , 以 及 如 何 调 整 C 库 和 映 像<br />

内 存 映 射 以 适 应 您 的 目 标 系 统 。<br />

第 3 章 使 用 过 程 调 用 标 准<br />

阅 读 此 章 , 了 解 如 何 使 用 <strong>ARM</strong>-Thumb 过 程 调 用 标 准 。 使 用 此 标 准<br />

可 以 更 方 便 地 确 保 分 别 编 译 和 汇 编 的 模 块 可 以 协 同 工 作 。<br />

第 4 章 <strong>ARM</strong> 和 Thumb 交 互 操 作<br />

阅 读 此 章 , 了 解 编 写 实 现 Thumb ® 指 令 集 的 处 理 器 代 码 时 , 如 何 在<br />

<strong>ARM</strong> 状 态 和 Thumb 状 态 之 间 切 换 的 详 细 信 息 。<br />

第 5 章 混 合 使 用 C、 C++ 和 汇 编 语 言<br />

阅 读 此 章 , 了 解 如 何 编 写 C、 C++ 和 <strong>ARM</strong> 汇 编 语 言 混 合 代 码 的 详<br />

细 信 息 。 它 还 描 述 如 何 从 C 和 C++ 使 用 <strong>ARM</strong> 内 联 和 嵌 入 式 汇 编 程<br />

序 。<br />

vi © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


序 言<br />

第 6 章 处 理 处 理 器 异 常<br />

阅 读 此 章 , 了 解 如 何 处 理 <strong>ARM</strong> 处 理 器 支 持 的 各 种 类 型 异 常 的 详 细<br />

信 息 。<br />

第 7 章 调 试 通 信 通 道<br />

阅 读 此 章 , 了 解 如 何 使 用 调 试 通 信 通 道 (DCC) 的 描 述 。<br />

印 刷 约 定<br />

本 书 中 使 用 了 下 列 印 刷 约 定 :<br />

等 宽 字 体 表 示 可 在 键 盘 上 输 入 的 文 本 , 例 如 命 令 、 文 件 和 程 序 名 称 及 源 代 码 。<br />

等 宽 字 体<br />

等 宽 斜 体<br />

等 宽 粗 体<br />

斜 体<br />

粗 体<br />

表 示 命 令 或 选 项 所 允 许 的 缩 写 词 。 可 以 输 入 带 下 划 线 文 本 来 代 替<br />

整 个 命 令 或 选 项 名 称 。<br />

表 示 命 令 和 函 数 的 自 变 量 , 函 数 中 的 自 变 量 将 由 指 定 的 值 代 替 。<br />

表 示 在 示 例 代 码 外 使 用 的 语 言 关 键 字 。<br />

突 出 显 示 重 要 的 备 注 , 介 绍 特 殊 术 语 , 表 示 内 部 交 叉 引 用 , 以 及 引<br />

用 。<br />

突 出 显 示 界 面 元 素 ( 如 菜 单 名 称 )。 有 时 候 也 用 于 在 描 述 性 的 列 表<br />

中 进 行 强 调 , 以 及 表 示 <strong>ARM</strong> 处 理 器 信 号 名 称 。<br />

更 深 入 的 读 物<br />

本 节 列 出 来 自 <strong>ARM</strong> Limited 和 第 三 方 的 出 版 物 , 其 中 提 供 了 为 <strong>ARM</strong> 系 列 处 理 器<br />

开 发 代 码 的 附 加 信 息 。<br />

<strong>ARM</strong> 定 期 对 其 文 档 进 行 更 新 和 修 正 。 有 关 当 前 勘 误 表 和 增 补 以 及 <strong>ARM</strong> 常 见 问<br />

题 的 信 息 , 请 访 问 http://www.arm.com。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 vii


序 言<br />

<strong>ARM</strong> 出 版 物<br />

本 手 册 包 含 开 发 <strong>ARM</strong> 系 列 处 理 器 应 用 程 序 的 一 般 信 息 。 有 关 其 它 组 件 的 信 息 ,<br />

请 参 阅 以 下 RVCT 文 档 集 中 的 手 册 。<br />

• <strong>RealView</strong> 编 译 工 具 2.0 版 入 门 指 南 (<strong>ARM</strong> DUI 0202) ;<br />

• <strong>RealView</strong> 编 译 工 具 2.0 版 汇 编 程 序 指 南 (<strong>ARM</strong> DUI 0204) ;<br />

• <strong>RealView</strong> 编 译 工 具 2.0 版 编 译 程 序 和 库 指 南 (<strong>ARM</strong> DUI 0205) ;<br />

• <strong>RealView</strong> 编 译 工 具 2.0 版 链 接 程 序 和 实 用 程 序 指 南 (<strong>ARM</strong> DUI 0206)。<br />

随 <strong>RealView</strong> 编 译 工 具 提 供 了 下 列 附 加 文 档 :<br />

• <strong>ARM</strong> FLEXlm 许 可 证 管 理 指 南 (<strong>ARM</strong> DUI 0209)。 此 指 南 以 DynaText 和<br />

PDF 格 式 提 供 。<br />

• <strong>ARM</strong> 体 系 结 构 参 考 手 册 (<strong>ARM</strong> DDI 0100)。 该 手 册 作 为 联 机 图 书 的 组 成 部 分<br />

以 DynaText 格 式 提 供 , 并 且 以 PDF 文 件 DDI0100E_<strong>ARM</strong>_<strong>ARM</strong>.pdf 形 式 提 供 , 该<br />

文 件 位 于 install_directory\Documentation\<strong>ARM</strong><strong>ARM</strong>\5.0\release\windows\PDF 中 。<br />

• <strong>ARM</strong> ELF 规 范 (SWS ESPC 0003)。 这 是 以 PDF 文 件 格 式 提 供 的 , 文 件 名 为<br />

<strong>ARM</strong>ELF.pdf, 位 于<br />

install_directory\Documentation\Specifications\1.0\release\platform\PDF 下 。<br />

• TIS DWARF 2 规 范 。 这 是 以 PDF 文 件 格 式 提 供 的 , 文 件 名 为<br />

TIS-DWARF2.pdf , 位 于<br />

install_directory\Documentation\Specifications\1.0\release\platform\PDF 下 。<br />

• <strong>ARM</strong>-Thumb 过 程 调 用 标 准 规 范 。 这 是 以 PDF 文 件 格 式 提 供 的 , 文 件 名 为<br />

ATPCS.pdf, 位 于<br />

install_directory\Documentation\Specifications\1.0\release\platform\PDF 下 。<br />

此 外 , 可 参 考 下 列 文 档 来 了 解 与 <strong>ARM</strong> 产 品 相 关 的 特 定 信 息 :<br />

• <strong>RealView</strong> <strong>ARM</strong>ulator ISS v1.3 用 户 指 南 (<strong>ARM</strong> DUI 0207) ;<br />

• Multi-ICE 2.2 版 用 户 指 南 (<strong>ARM</strong> DUI 0048), 或 更 高 版 本 ;<br />

• <strong>ARM</strong> 参 考 外 设 规 范 (<strong>ARM</strong> DDI 0062) ;<br />

• 您 的 硬 件 设 备 的 <strong>ARM</strong> 数 据 表 或 技 术 参 考 手 册 。<br />

其 它 出 版 物<br />

下 面 这 本 书 提 供 了 关 于 <strong>ARM</strong> 体 系 结 构 的 一 般 性 信 息 :<br />

• <strong>ARM</strong> System-on-chip Architecture (second edition), Furber, S., (2000). Addison<br />

Wesley. ISBN 0-201-67519-6.<br />

viii © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


序 言<br />

反 馈<br />

<strong>ARM</strong> Limited 欢 迎 用 户 为 <strong>RealView</strong> 编 译 工 具 及 其 文 档 提 供 反 馈 意 见 。<br />

对 <strong>RealView</strong> 编 译 工 具 的 反 馈 信 息<br />

如 果 您 有 关 于 <strong>RealView</strong> 编 译 工 具 的 任 何 问 题 , 请 与 您 的 供 货 商 联 系 。 为 了 帮 助<br />

它 们 提 供 快 速 而 有 用 的 响 应 , 请 提 供 :<br />

• 您 的 姓 名 和 公 司 ;<br />

• 产 品 的 序 列 号 ;<br />

• 您 正 在 使 用 的 版 本 的 详 细 信 息 ;<br />

• 您 正 在 运 行 的 平 台 的 详 细 信 息 , 例 如 硬 件 平 台 、 操 作 系 统 类 型 和 版 本 ;<br />

• 能 复 现 问 题 的 一 小 段 独 立 示 例 代 码 ;<br />

• 清 晰 地 解 释 您 期 望 发 生 的 和 实 际 发 生 的 事 件 ;<br />

• 您 使 用 的 命 令 , 包 括 任 何 命 令 行 选 项 ;<br />

• 阐 明 问 题 的 输 出 样 例 ;<br />

• 工 具 版 本 字 符 串 , 包 括 版 本 号 和 日 期 。<br />

对 本 书 的 反 馈<br />

如 果 您 注 意 到 本 书 中 有 任 何 错 误 和 遗 漏 , 请 发 送 电 子 邮 件 到 errata@arm.com, 并<br />

提 供 :<br />

• 文 档 标 题 ;<br />

• 文 档 编 号 ;<br />

• 您 的 注 释 所 适 用 的 页 码 ;<br />

• 问 题 的 简 要 说 明 。<br />

也 欢 迎 对 增 补 和 改 进 提 出 一 般 性 建 议 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 ix


序 言<br />

x © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


第 1 章<br />

简 介<br />

本 章 介 绍 了 <strong>RealView</strong> 编 译 工 具 (RVCT)。 其 中 包 含 下 列 各 部 分 :<br />

• 第 1-2 页 的 关 于 RVCT 开 发 者 指 南 ;<br />

• 第 1-5 页 的 通 用 程 序 设 计 问 题 ;<br />

• 第 1-10 页 的 为 <strong>ARM</strong> 处 理 器 开 发 代 码 。<br />

备 注<br />

本 文 档 中 给 出 的 示 例 中 编 译 程 序 、 汇 编 程 序 和 链 接 程 序 的 选 项 使 用 了 单 短 线 。 在<br />

RVCT v2.0 中 , 可 以 使 用 双 短 线 -- 指 定 命 令 行 关 键 字 , 比 如 --partial。 但 是 , 编<br />

译 程 序 中 的 单 字 母 选 项 , 如 -E, 则 没 有 等 价 的 双 短 线 选 项 。<br />

为 了 向 后 兼 容 , 仍 支 持 以 前 版 本 的 ADS 和 RVCT 中 使 用 的 单 短 线 命 令 行 选 项 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 1-1


简 介<br />

1.1 关 于 RVCT 开 发 者 指 南<br />

本 书 包 括 开 发 <strong>ARM</strong> 系 列 RISC 系 列 处 理 器 代 码 的 特 定 问 题 的 帮 助 信 息 。 通 常 ,<br />

本 书 的 各 章 都 假 设 您 使 用 <strong>RealView</strong> 编 译 工 具 (RVCT) 来 开 发 代 码 。<br />

RVCT 由 一 套 工 具 连 同 支 持 文 档 和 示 例 组 成 , 允 许 您 为 <strong>ARM</strong> 系 列 RISC 处 理 器<br />

编 写 和 编 译 应 用 程 序 。 可 以 使 用 RVCT 来 编 译 C、C++ 或 <strong>ARM</strong> 汇 编 语 言 程 序 。<br />

RVCT 工 具 箱 包 含 以 下 主 要 组 件 :<br />

• 命 令 行 开 发 工 具 ;<br />

• 实 用 程 序 ;<br />

• 支 持 软 件 。<br />

有 关 RVCT 文 件 的 列 表 , 请 参 阅 第 vii 页 的 更 深 入 的 读 物 。<br />

1.1.1 示 例 代 码<br />

本 书 中 很 多 示 例 的 代 码 都 在 下 面 的 路 径 中 :<br />

install_directory\RVCT\Examples\2.0\release\platform<br />

其 中 install_directory 为 RVCT v2.0 的 安 装 路 径 ,platform 是 windows 或 unix。 为 更 明<br />

了 , 在 本 文 档 的 其 它 地 方 将 这 个 路 径 称 为 Examples_directory。<br />

此 外 , 包 含 此 路 径 下 还 包 含 本 书 未 介 绍 的 示 例 代 码 。 请 参 阅 每 个 示 例 目 录 中 的<br />

readme.txt 文 件 获 得 更 多 信 息 。 示 例 安 装 在 以 下 几 个 子 目 录 中 :<br />

asm<br />

cpp<br />

该 目 录 包 含 了 <strong>ARM</strong> 汇 编 语 言 程 序 设 计 的 几 个 示 例 。 <strong>RealView</strong> 编 译<br />

工 具 2.0 版 汇 编 程 序 指 南 中 使 用 了 这 些 示 例 。<br />

该 目 录 包 含 了 几 个 简 单 的 C++ 示 例 。 此 外 ,rw 子 目 录 包 含 了 Rogue<br />

Wave 手 册 和 教 学 示 例 。<br />

databort 该 目 录 包 含 了 标 准 数 据 中 断 处 理 程 序 的 设 计 文 档 和 示 例 代 码 。<br />

dcc<br />

该 目 录 包 含 了 说 明 如 何 使 用 Debug Communications Channel 的 示 例<br />

代 码 。 该 示 例 将 在 第 7 章 调 试 通 信 通 道 中 介 绍 。<br />

1-2 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


简 介<br />

cached_dhry 该 目 录 包 含 了 初 始 化 缓 存 和 TCM 例 程 的 示 例 , 它 位 于 Dhrystone 示<br />

例 附 近 。<br />

dhry 该 目 录 包 含 了 Dhrystone 源 代 码 。<br />

dhryansi 该 目 录 包 含 了 Dhrystone 的 ANSI C 版 本 。<br />

emb_sw_dev<br />

embedded<br />

该 目 录 包 含 了 第 2 章 嵌 入 式 软 件 开 发 所 参 考 的 示 例 项 目 。 包 括 以<br />

下 子 目 录 :<br />

buildn 批 处 理 和 make 文 件 以 编 译 示 例 项 目 。<br />

dhry<br />

Dhrystone 基 准 程 序 的 源 文 件 该 程 序 为 每 个 buildn 目 录 中<br />

的 示 例 项 目 提 供 了 代 码 基 础 。<br />

source 编 译 示 例 项 目 所 需 要 的 所 有 其 它 源 文 件 。<br />

include 用 户 定 义 的 头 文 件 。<br />

scatter 用 于 构 建 示 例 项 目 的 分 散 文 件 。<br />

该 目 录 包 含 了 说 明 如 何 为 ROM 编 写 代 码 的 源 代 码 示 例 。 这 些 示 例<br />

适 用 于 <strong>ARM</strong> Integrator 电 路 板 的 应 用 情 形 。<br />

explasm 该 目 录 包 含 了 额 外 的 <strong>ARM</strong> 汇 编 语 言 示 例 。<br />

fft_5te <strong>ARM</strong> 体 系 结 构 v5TE 的 快 速 傅 里 叶 变 换 优 化 源 代 码 。<br />

inline<br />

interwork<br />

mmugen<br />

picpid<br />

sorts<br />

该 目 录 包 含 了 说 明 在 编 译 <strong>ARM</strong> C 和 C++ 代 码 时 如 何 使 用 内 联 汇 编<br />

程 序 的 示 例 。 这 些 示 例 将 在 第 5 章 混 合 使 用 C、 C++ 和 汇 编 语 言<br />

中 介 绍 。<br />

该 目 录 包 含 了 说 明 如 何 在 <strong>ARM</strong> 代 码 和 Thumb 代 码 之 间 进 行 交 互<br />

的 示 例 。 这 些 示 例 将 在 第 4 章 <strong>ARM</strong> 和 Thumb 交 互 操 作 中 介 绍 。<br />

该 目 录 包 含 了 MMUgen 实 用 程 序 的 源 代 码 和 文 档 。 这 个 实 用 工 具<br />

可 从 描 述 虚 拟 至 物 理 地 址 所 需 要 的 转 换 规 则 文 件 中 生 成 MMU 页 表<br />

数 据 。<br />

该 目 录 包 含 了 说 明 如 何 编 写 位 置 无 关 代 码 的 一 个 示 例 。 有 关 详 细 说<br />

明 , 请 参 阅 readme.txt。<br />

该 目 录 包 含 了 比 较 <strong>ARM</strong> C 库 中 所 使 用 的 插 入 排 序 法 、 希 尔 排 序 法<br />

和 快 速 排 序 法 的 示 例 代 码 。<br />

swi 该 目 录 包 含 了 SWI 处 理 程 序 的 一 个 示 例 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 1-3


简 介<br />

unicode 该 项 目 录 包 含 了 能 够 检 测 RVCT v2.0 支 持 的 多 字 节 字 符 的 示 例 代 码 。<br />

vfpsupport<br />

该 目 录 中 包 含 了 赋 予 并 实 现 向 量 浮 点 (VFP) 运 算 的 示 例 代 码 。 并 包<br />

含 了 使 用 VFP 时 配 置 调 试 系 统 的 各 种 实 用 工 具 文 件 。<br />

1-4 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


简 介<br />

1.2 通 用 程 序 设 计 问 题<br />

<strong>ARM</strong> 系 列 处 理 器 是 RISC 处 理 器 。 很 多 给 出 有 效 代 码 的 程 序 设 计 策 略 都 源 于<br />

RISC 处 理 器 。 和 很 多 RISC 处 理 器 一 样 ,<strong>ARM</strong> 系 列 处 理 器 被 设 计 用 来 存 取 对 齐<br />

数 据 , 即 存 储 “ 字 ” 的 地 址 为 四 的 倍 数 ,“ 半 字 ” 时 为 二 的 倍 数 。 该 数 据 按 其 自<br />

然 尺 寸 边 界 定 位 。<br />

<strong>ARM</strong> 编 译 程 序 通 常 将 全 局 变 量 对 齐 到 这 些 自 然 尺 寸 边 界 上 , 以 便 通 过 使 用 LDR<br />

和 STR 指 令 有 效 地 存 取 这 些 变 量 。<br />

这 与 多 数 CISC 体 系 结 构 不 同 , 其 使 用 指 令 直 接 存 取 未 对 齐 的 数 据 。 因 而 , 在 从<br />

CISC 体 系 结 构 向 <strong>ARM</strong> 处 理 器 移 植 遗 留 代 码 是 必 须 予 以 注 意 。 存 取 未 对 齐 数 据<br />

在 代 码 尺 寸 或 性 能 都 不 利 。<br />

下 面 的 各 节 详 细 地 探 讨 了 程 序 设 计 问 题 :<br />

• 有 效 地 使 用 <strong>ARM</strong>-Thumb 过 程 调 用 标 准 ;<br />

• 未 对 齐 指 针 ;<br />

• 第 1-6 页 的 结 构 中 的 未 对 齐 字 段 ;<br />

• 第 1-8 页 的 用 于 半 字 存 取 的 非 对 齐 LDR ;<br />

• 第 1-9 页 的 移 植 代 码 并 检 测 非 对 齐 存 取 。<br />

1.2.1 有 效 地 使 用 <strong>ARM</strong>-Thumb 过 程 调 用 标 准<br />

在 <strong>ARM</strong>-Thumb 过 程 调 用 标 准 下 <strong>ARM</strong> 编 译 程 序 将 头 四 个 整 数 大 小 的 函 数 参 数 传<br />

递 至 寄 存 器 r0 到 r3。 其 它 参 数 传 递 到 栈 中 。 这 意 味 着 :<br />

• 大 量 的 参 数 通 过 引 用 的 方 法 传 递 更 为 有 效 , 比 如 结 构 ,<br />

• 如 有 可 能 , 函 数 限 制 使 用 四 个 或 更 少 的 整 数 大 小 的 参 数 将 更 为 有 效 。<br />

1.2.2 未 对 齐 指 针<br />

<strong>ARM</strong> 编 译 程 序 期 望 正 常 的 C 指 针 指 向 存 储 器 中 对 齐 的 字 , 因 为 这 可 使 编 译 程 序<br />

生 成 更 有 效 的 代 码 。<br />

比 如 , 如 果 指 针 int * 被 用 来 读 取 一 个 字 ,<strong>ARM</strong> 编 译 程 序 使 用 生 成 代 码 中 的 一 条<br />

LDR 指 令 。 当 地 址 为 四 的 倍 数 ( 即 在 一 个 字 的 边 界 ) 即 能 正 确 读 取 。 但 是 , 如 果<br />

该 地 址 不 是 四 的 倍 数 , 那 么 , 一 条 LDR 指 令 返 回 一 个 循 环 移 位 结 果 , 而 不 是 执 行<br />

真 正 的 未 对 齐 字 载 入 。 循 环 移 位 结 果 取 决 于 系 统 的 偏 移 量 和 端 序 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 1-5


简 介<br />

例 如 , 如 果 代 码 从 指 针 指 向 的 地 址 0x8006 载 入 数 据 , 则 期 望 从 0x8006、 0x8007、<br />

0x8008 和 0x8009 载 入 字 节 的 内 容 。 但 是 , 在 <strong>ARM</strong> 处 理 器 上 , 这 个 存 取 载 入 了<br />

0x8004、 0x8005、 0x8006 和 0x8007 字 节 的 循 环 移 位 内 容 。<br />

因 而 , 如 果 想 将 指 针 定 义 到 一 个 可 在 任 何 地 址 ( 即 非 自 然 对 齐 ) 的 字 中 , 那 么<br />

在 定 义 该 指 针 时 , 必 须 使 用 __packed 限 定 符 来 定 义 指 针 :<br />

__packed int *pi; // pointer to unaligned int<br />

然 后 ,<strong>ARM</strong> 编 译 程 序 不 使 用 LDR, 而 是 生 成 正 确 存 取 该 值 的 代 码 , 而 不 必 考 虑 指<br />

针 对 齐 状 况 。 所 生 成 的 代 码 是 字 节 存 取 的 一 个 序 列 , 或 者 取 决 于 编 译 选 项 、 跟 变<br />

量 对 齐 相 关 的 移 位 和 屏 蔽 。 这 会 导 致 性 能 和 代 码 大 小 的 损 失 。<br />

备 注<br />

千 万 不 要 用 __packed 来 存 取 存 储 器 映 射 的 外 围 寄 存 器 , 因 为 <strong>ARM</strong> 编 译 程 序 可 使<br />

用 多 个 存 储 器 存 取 来 重 新 获 取 数 据 。 因 而 , 可 对 附 近 的 位 置 进 行 存 取 , 它 们 可 能<br />

对 应 于 其 它 外 部 寄 存 器 。 当 使 用 了 位 字 段 时 , <strong>ARM</strong> 编 译 程 序 当 前 存 取 整 个 部<br />

分 , 而 不 只 是 所 指 定 的 字 段 。<br />

1.2.3 结 构 中 的 未 对 齐 字 段<br />

与 全 局 变 量 位 于 其 自 然 尺 寸 边 界 相 同 , 结 构 中 的 字 段 也 如 此 。 就 是 说 编 译 程 序 经<br />

常 要 在 字 段 间 插 入 填 充 字 节 来 确 保 字 段 对 齐 。 当 编 译 程 序 插 入 填 充 字 节 时 , 使 用<br />

选 项 -W+s 编 译 产 生 一 个 警 告 。<br />

有 时 , 可 能 不 希 望 这 样 的 情 况 发 生 。 可 使 用 __packed 限 定 符 来 创 建 字 段 之 间 没<br />

有 填 充 字 节 的 结 构 , 且 这 些 结 构 需 要 非 对 齐 存 取 。<br />

如 果 <strong>ARM</strong> 编 译 程 序 知 道 特 定 结 构 的 对 齐 , 它 可 以 确 定 所 存 取 的 字 段 是 否 在 一 个<br />

充 填 结 构 中 是 对 齐 的 。 在 这 些 情 况 下 , 编 译 程 序 尽 可 能 地 采 用 更 有 效 的 对 齐 字 或<br />

半 字 存 取 。 否 则 , 编 译 程 序 使 用 多 个 对 齐 存 储 器 存 取 (LDR、STR、LDM 和 STM) 与<br />

固 定 移 位 和 屏 蔽 相 结 合 来 存 取 存 储 器 中 正 确 的 字 节 。<br />

对 非 对 齐 元 素 的 存 取 是 通 过 内 联 还 是 通 过 调 用 一 个 函 数 来 完 成 , 由 编 译 程 序<br />

-Ospace( 默 认 , 调 用 一 个 函 数 ) 和 -Otime( 执 行 非 对 齐 存 取 内 联 ) 选 项 来 控 制 。<br />

1-6 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


简 介<br />

例 如 :<br />

1. 创 建 一 个 文 件 foo.c, 它 包 括 :<br />

__packed struct mystruct {<br />

int aligned_i;<br />

short aligned_s;<br />

int unaligned_i;<br />

};<br />

struct mystruct S1;<br />

int foo (int a, short b)<br />

{<br />

S1.aligned_i=a;<br />

S1.aligned_s=b;<br />

return S1.unaligned_i;<br />

}<br />

2. 使 用 armcc -c -Otime foo.c 编 译 。 所 生 成 的 代 码 为 :<br />

MOV r2,r0<br />

LDR r0,|L1.84|<br />

MOV r12,r2,LSR #8<br />

STRB r2,[r0,#0]<br />

STRB r12,[r0,#1]<br />

MOV r12,r2,LSR #16<br />

STRB r12,[r0,#2]<br />

MOV r12,r2,LSR #24<br />

STRB r12,[r0,#3]<br />

MOV r12,r1,LSR #8<br />

STRB r1,[r0,#4]<br />

STRB r12,[r0,#5]<br />

ADD r0,r0,#6<br />

BIC r3,r0,#3<br />

AND r0,r0,#3<br />

LDMIA r3,{r3,r12}<br />

MOV r0,r0,LSL #3<br />

MOV r3,r3,LSR r0<br />

RSB r0,r0,#0x20<br />

ORR r0,r3,r12,LSL r0<br />

BX lr<br />

然 而 , 可 以 给 编 译 程 序 更 多 的 信 息 , 使 其 能 知 道 哪 个 字 段 是 对 齐 的 , 哪 个<br />

字 段 不 是 。 为 此 , 必 须 将 未 对 齐 字 段 声 明 为 __packed, 并 从 struct 本 身 除<br />

去 __packed 属 性 。 这 是 推 荐 的 方 法 , 并 且 是 保 证 struct 中 自 然 对 齐 成 员 快<br />

速 存 取 的 唯 一 方 法 。 而 且 , 哪 个 字 段 是 未 对 齐 的 也 更 清 楚 , 但 在 struct 中<br />

增 加 或 删 除 字 段 时 需 要 小 心 。<br />

3. 现 在 , 修 改 foo.c 中 的 结 构 定 义 为 :<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 1-7


简 介<br />

struct mystruct {<br />

int aligned_i;<br />

short aligned_s;<br />

__packed int unaligned_i;<br />

};<br />

struct mystruct S1;<br />

4. 编 译 foo.c 和 下 列 代 码 , 生 成 了 更 有 效 的 代 码 :<br />

MOV r2,r0<br />

LDR r0,|L1.32|<br />

STR r2,[r0,#0]<br />

STRH r1,[r0,#4]<br />

LDMIB r0,{r3,r12}<br />

MOV r0,r3,LSR #16<br />

ORR r0,r0,r12,LSL #16<br />

BX lr<br />

同 一 原 理 适 应 于 联 合 。 使 用 在 存 储 器 中 未 对 齐 的 联 合 组 件 的 __packed 属 性 。<br />

备 注<br />

任 何 通 过 指 针 存 取 的 __packed 对 象 都 有 未 知 的 对 齐 , 即 使 是 充 填 结 构 。<br />

1.2.4 用 于 半 字 存 取 的 非 对 齐 LDR<br />

有 些 情 况 下 , <strong>ARM</strong> 编 译 程 序 可 特 意 生 成 非 对 齐 LDR 指 令 。 特 别 是 编 译 程 序 从 存<br />

储 器 中 载 入 半 字 时 将 使 用 该 方 法 。 这 是 因 为 , 通 过 使 用 相 应 地 址 , 所 需 的 半 字 可<br />

以 载 入 到 寄 存 器 顶 部 的 一 半 , 然 后 向 底 部 移 位 一 半 。 这 只 需 要 一 个 存 储 器 的 存<br />

取 , 而 使 用 LDRB 指 令 做 同 样 的 操 作 需 要 两 个 存 储 器 的 存 取 , 还 需 要 将 这 两 个 字<br />

节 合 并 在 一 起 的 指 令 。 在 <strong>ARM</strong> 体 系 结 构 v3 和 其 早 期 版 本 中 , 通 常 使 用 该 方 法<br />

进 行 所 有 半 字 载 入 。 在 <strong>ARM</strong>v4 和 其 以 后 版 本 中 , 就 不 经 常 这 么 做 了 , 因 为 有 了<br />

专 门 的 半 字 载 入 指 令 , 但 是 , 非 对 齐 仍 可 能 会 生 成 LDR 指 令 。 比 如 在 一 个 充 填 结<br />

构 中 存 取 一 个 非 对 齐 short。<br />

备 注<br />

如 果 使 用 --memaccess +L41 编 译 程 序 选 项 使 其 可 用 , 这 样 的 非 对 齐 LDR 指 令 仅 由<br />

RVCT 编 译 程 序 生 成 。<br />

1-8 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


简 介<br />

1.2.5 移 植 代 码 并 检 测 非 对 齐 存 取<br />

其 它 体 系 结 构 ( 如 x86 CISC) 所 遗 留 的 代 码 , 可 能 会 使 用 在 <strong>ARM</strong> 处 理 器 上 不<br />

起 作 用 的 指 针 执 行 对 非 对 齐 数 据 的 存 取 。 这 是 不 可 移 植 的 代 码 , 在 期 望 对 齐 数 据<br />

的 RISC 体 系 结 构 中 , 必 须 识 别 并 更 改 此 类 存 取 才 能 使 其 发 生 正 确 存 取 数 据 。<br />

识 别 非 对 齐 存 取 可 能 会 很 困 难 , 因 为 使 用 非 对 齐 地 址 进 行 的 载 入 或 存 储 操 作 产<br />

生 不 正 确 的 动 作 。 追 踪 到 底 是 哪 部 分 的 C 源 程 序 造 成 了 这 个 问 题 是 很 困 难 的 。<br />

具 有 完 整 存 储 器 管 理 单 元 (MMUs) 的 <strong>ARM</strong> 处 理 器 , 例 如 ,<strong>ARM</strong>920T , 支 持 可<br />

选 的 对 齐 检 测 , 处 理 器 检 测 每 一 次 的 存 取 以 确 保 其 被 正 确 地 对 齐 。 如 果 出 现 不 正<br />

确 的 对 齐 存 取 , MMU 产 生 数 据 中 断 。<br />

对 于 <strong>ARM</strong>7TDMI ® 等 简 单 的 内 核 , 建 议 在 ASIC/ASSP 内 部 实 现 对 齐 检 测 。 可 以<br />

使 用 相 对 <strong>ARM</strong> 内 核 是 额 外 的 外 部 硬 件 体 来 完 成 这 一 点 , 由 其 监 控 每 次 数 据 的 存<br />

取 规 模 和 存 取 地 址 总 线 的 最 低 有 效 位 。 在 非 对 齐 存 取 的 情 况 下 , 可 以 通 过 配 置<br />

ASIC/ASSP 来 产 生 中 断 信 号 。 <strong>ARM</strong> Limited 建 议 从 其 它 体 系 结 构 移 植 代 码 的<br />

ASIC/ASSP 设 备 中 要 包 含 这 样 的 逻 辑 。<br />

如 果 将 系 统 配 置 为 非 对 齐 存 取 进 行 中 断 , 则 必 须 安 装 数 据 中 断 异 常 处 理 程 序 。 出<br />

现 非 对 齐 存 取 时 , 进 入 数 据 中 断 处 理 程 序 , 并 由 此 识 别 位 于 (r14-8) 的 出 错 数 据<br />

存 取 指 令 。<br />

一 旦 识 别 出 , 必 须 通 过 改 变 C 源 程 序 来 修 复 数 据 的 存 取 。 使 用 下 列 指 令 可 有 条<br />

件 地 完 成 修 复 :<br />

#ifdef __arm<br />

#define PACKED __packed<br />

#else<br />

#define PACKED<br />

#endif<br />

:<br />

PACKED int *pi;<br />

:<br />

由 于 代 码 大 小 和 性 能 上 的 开 销 , 最 好 尽 可 能 少 采 用 存 取 非 对 齐 数 据 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 1-9


简 介<br />

1.3 为 <strong>ARM</strong> 处 理 器 开 发 代 码<br />

本 书 提 供 了 部 分 最 常 用 的 <strong>ARM</strong> 程 序 设 计 任 务 的 信 息 和 示 例 代 码 。 下 面 的 章 节 总<br />

结 了 每 章 的 主 要 内 容 。<br />

• 嵌 入 式 软 件 开 发 ;<br />

• 第 1-11 页 的 使 用 过 程 调 用 标 准 ;<br />

• 第 1-11 页 的 <strong>ARM</strong> 与 Thumb 代 码 交 互 ;<br />

• 第 1-12 页 的 混 合 使 用 C、 C++ 和 汇 编 语 言 ;<br />

• 第 1-12 页 的 处 理 处 理 器 异 常 。<br />

1.3.1 嵌 入 式 软 件 开 发<br />

很 多 为 基 于 <strong>ARM</strong> 系 统 编 写 的 应 用 程 序 都 是 嵌 入 式 应 用 程 序 , 它 们 存 储 在 ROM<br />

中 并 在 复 位 时 执 行 。 编 写 嵌 入 式 操 作 系 统 , 或 编 写 在 复 位 时 执 行 的 嵌 入 式 应 用<br />

程 序 ( 无 操 作 系 统 ) 时 要 考 虑 很 多 因 素 , 包 括 :<br />

• 地 址 重 映 射 , 如 初 始 化 使 ROM 的 地 址 位 于 0x0000, 然 后 将 RAM 重 映 射 到<br />

地 址 0x0000 ;<br />

• 初 始 化 环 境 和 应 用 程 序 ;<br />

• 链 接 一 个 可 执 行 的 嵌 入 映 象 将 代 码 和 数 据 放 置 在 存 储 器 的 特 定 位 置 。<br />

复 位 时 ,<strong>ARM</strong> 内 核 通 常 从 地 址 0x0000 开 始 执 行 指 令 。 对 于 嵌 入 式 系 统 , 这 意 味<br />

着 系 统 复 位 时 ,ROM 一 定 是 在 地 址 0x0000 处 。 但 是 ,ROM 一 般 要 比 RAM 慢 ,<br />

且 通 常 只 有 8 或 16 位 宽 。 由 此 影 响 了 异 常 处 理 的 速 度 。 令 ROM 处 在 地 址<br />

0x0000 意 味 着 异 常 向 量 不 能 被 更 改 。 通 常 的 策 略 是 在 启 动 后 将 ROM 重 映 射 到<br />

RAM 并 将 异 常 向 量 从 ROM 复 制 到 RAM。 有 关 详 细 信 息 请 参 阅 第 2-25 页 的<br />

ROM/RAM 重 新 映 射 。<br />

复 位 后 , 嵌 入 式 应 用 程 序 或 操 作 系 统 必 须 对 系 统 进 行 初 始 化 , 包 括 :<br />

• 初 始 化 执 行 环 境 , 如 异 常 向 量 、 栈 和 I/O 外 设 ;<br />

• 初 始 化 应 用 程 序 , 比 如 将 非 零 可 写 数 据 的 初 始 值 复 制 到 可 写 数 据 区 并 将 ZI<br />

数 据 区 清 零 。<br />

有 关 详 细 信 息 请 参 阅 第 2-23 页 的 初 始 化 序 列 。<br />

1-10 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


简 介<br />

嵌 入 式 系 统 通 常 采 用 复 杂 的 存 储 器 配 置 。 例 如 , 嵌 入 式 系 统 可 能 会 将 高 速 32 位<br />

RAM 用 于 追 求 性 能 的 代 码 ( 如 中 断 处 理 程 序 和 栈 ), 将 较 慢 的 16 位 RAM 用 于<br />

应 用 程 序 RW 数 据 , 将 ROM 用 于 常 规 应 用 程 序 代 码 。 可 以 使 用 链 接 程 序 的 分 散<br />

载 入 机 制 构 建 适 合 复 杂 系 统 的 可 执 行 映 象 。 例 如 , 分 散 载 入 描 述 文 件 可 指 定 单 独<br />

的 代 码 和 数 据 区 的 载 入 地 址 和 执 行 地 址 。 有 关 影 响 嵌 入 式 应 用 程 序 ( 如 半 主 机 )<br />

相 关 主 题 的 信 息 和 一 系 列 已 处 理 过 的 示 例 , 请 参 阅 第 2 章 嵌 入 式 软 件 开 发 。<br />

1.3.2 使 用 过 程 调 用 标 准<br />

为 确 保 使 分 别 编 译 和 汇 编 的 模 块 能 够 协 同 工 作 , 必 须 遵 循 定 义 寄 存 器 用 法 和 栈<br />

约 定 的 <strong>ARM</strong>-Thumb 过 程 调 用 标 准 (ATPCS)。 该 基 本 标 准 中 有 很 多 变 量 。<strong>ARM</strong> 编<br />

译 程 序 总 是 生 成 与 所 选 ATPCS 变 量 一 致 的 代 码 。 如 果 需 要 , 链 接 程 序 会 选 择 一<br />

个 合 适 标 准 的 C 或 C++ 库 来 链 接 。<br />

为 <strong>ARM</strong> 开 发 代 码 时 , 必 须 选 择 合 适 的 ATPCS 变 量 。 例 如 , 如 果 编 写 <strong>ARM</strong> 与<br />

Thumb 状 态 间 交 互 的 代 码 , 必 须 选 择 编 译 程 序 和 汇 编 程 序 中 的 --apcs /interwork<br />

选 项 。<br />

如 用 C 或 C++ 编 写 代 码 , 必 须 确 保 为 每 一 编 译 模 块 已 选 择 了 兼 容 的 ATPCS 选 项 。<br />

如 果 编 写 自 己 的 汇 编 语 言 例 程 , 必 须 确 保 与 相 应 的 ATPCS 变 量 一 致 。 有 关 详 细<br />

信 息 请 参 阅 第 3 章 使 用 过 程 调 用 标 准 。<br />

如 果 采 用 C 和 汇 编 语 言 混 合 编 写 , 请 确 保 理 解 ATPCS 的 含 意 。<br />

1.3.3 <strong>ARM</strong> 与 Thumb 代 码 交 互<br />

如 果 为 支 持 Thumb 16 位 指 令 集 的 <strong>ARM</strong> 处 理 器 编 写 代 码 , 可 按 需 要 将 <strong>ARM</strong> 和<br />

Thumb 代 码 混 合 使 用 。 如 用 C 或 C++ 编 写 代 码 , 必 须 使 用 --apcs /interwork 选<br />

项 进 行 编 译 。 链 接 程 序 检 测 何 时 从 Thumb 状 态 调 用 <strong>ARM</strong> 函 数 , 或 何 时 从 <strong>ARM</strong><br />

状 态 调 用 Thumb 函 数 并 改 变 调 用 及 返 回 进 程 , 或 者 在 必 要 时 插 入 交 互 胶 合 代 码<br />

来 改 变 处 理 器 状 态 。<br />

如 果 编 写 汇 编 语 言 代 码 , 必 须 确 保 遵 循 交 互 ATPCS 变 量 。 有 几 种 改 变 处 理 器 状<br />

态 的 方 法 , 取 决 于 目 标 体 系 结 构 的 版 本 。 有 关 详 细 信 息 请 参 阅 第 4 章 <strong>ARM</strong> 和<br />

Thumb 交 互 操 作 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 1-11


简 介<br />

1.3.4 混 合 使 用 C、 C++ 和 汇 编 语 言<br />

可 以 分 别 地 将 已 编 译 和 汇 编 的 C、 C++ 和 <strong>ARM</strong> 汇 编 语 言 模 块 混 用 在 您 的 程 序<br />

中 。 可 在 C 或 C++ 代 码 中 编 写 小 的 汇 编 语 言 例 程 。 使 用 <strong>ARM</strong> 编 译 程 序 的 内 联<br />

或 嵌 套 的 汇 编 程 序 编 译 这 些 例 程 。 但 是 , 如 果 使 用 内 联 或 嵌 套 的 汇 编 程 序 , 对 编<br />

写 的 汇 编 语 言 代 码 将 有 很 多 限 制 。 这 些 限 制 描 述 如 下 :<br />

• 第 5-7 页 的 内 联 汇 编 程 序 和 armasm 的 不 同 点 ;<br />

• 第 5-13 页 的 嵌 入 式 汇 编 语 句 的 限 制 。<br />

此 外 , 第 5 章 混 合 使 用 C、 C++ 和 汇 编 语 言 给 出 了 通 用 指 南 , 以 及 如 何 在 C、<br />

C++ 和 汇 编 语 言 模 块 间 调 用 的 示 例 。<br />

1.3.5 处 理 处 理 器 异 常<br />

<strong>ARM</strong> 处 理 器 识 别 出 以 下 异 常 类 型 :<br />

复 位<br />

在 处 理 器 复 位 管 脚 有 效 时 发 生 。 该 异 常 仅 在 处 理 器 上 电 时 、 或 上<br />

电 后 的 复 位 时 才 发 生 。 可 通 过 跳 转 到 复 位 向 量 (0x0000) 来 完 成 软 复<br />

位 。<br />

未 定 义 指 令 在 处 理 器 或 任 何 协 处 理 器 均 不 能 识 别 当 前 执 行 指 令 时 发 生 。<br />

软 件 中 断 (SWI)<br />

这 是 用 户 定 义 的 中 断 指 令 。 它 使 得 在 User 模 式 下 运 行 的 程 序 能 够<br />

请 求 在 Supervisor 模 式 下 运 行 的 特 权 操 作 , 如 RTOS 函 数 。<br />

预 取 中 断<br />

仅 当 处 理 器 试 图 执 行 一 个 从 非 法 地 址 预 取 的 指 令 时 才 发 生 。 非 法 地<br />

址 是 在 存 储 器 中 不 存 在 的 地 址 , 或 者 是 存 储 器 管 理 子 系 统 决 定 的 当<br />

前 模 式 下 处 理 器 不 可 存 取 的 地 址 。<br />

数 据 中 断 在 数 据 传 输 指 令 试 图 在 非 法 地 址 载 入 或 存 储 数 据 时 发 生 。<br />

1-12 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


简 介<br />

中 断 (IRQ) 处 理 器 外 部 中 断 请 求 管 脚 有 效 (LOW) 且 使 能 了 IRQ 中 断 (CPSR<br />

中 的 I 位 被 清 空 ) 时 发 生 。<br />

快 速 中 断 (FIQ)<br />

处 理 器 外 部 中 断 请 求 管 脚 有 效 (LOW) 且 使 能 了 FIQ 中 断 (CPSR 中<br />

的 F 位 被 清 空 ) 时 发 生 。 该 异 常 特 别 用 于 要 求 中 断 反 应 时 间 保 持 最<br />

短 的 情 况 。<br />

一 般 来 说 , 如 果 编 写 不 依 靠 操 作 系 统 来 处 理 异 常 的 应 用 程 序 ( 如 嵌 套 式 应 用 程<br />

序 ), 就 必 须 为 每 个 类 型 的 异 常 编 写 处 理 程 序 。<br />

在 一 个 异 常 类 型 有 多 个 源 的 情 况 下 , 比 如 SWI 或 IRQ 中 断 , 可 以 为 每 个 源 链 结<br />

异 常 处 理 程 序 。 有 关 详 细 信 息 请 参 阅 第 6-1 页 的 处 理 处 理 器 异 常 。<br />

对 于 能 够 处 理 Thumb 代 码 的 处 理 器 , 处 理 异 常 时 处 理 器 转 换 到 <strong>ARM</strong> 状 态 。 可<br />

以 用 <strong>ARM</strong> 代 码 编 写 异 常 处 理 程 序 , 或 者 用 一 胶 合 代 码 转 换 到 Thumb 状 态 。 有<br />

关 详 细 信 息 请 参 阅 第 6-9 页 的 返 回 地 址 和 返 回 指 令 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 1-13


简 介<br />

1-14 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


第 2 章<br />

嵌 入 式 软 件 开 发<br />

本 章 介 绍 了 在 有 或 没 有 目 标 系 统 存 在 的 情 况 下 , 如 何 利 用 RVCT 开 发 嵌 入 式 应<br />

用 程 序 。 它 包 含 以 下 几 个 部 分 :<br />

• 第 2-2 页 的 关 于 嵌 入 式 软 件 开 发 ;<br />

• 第 2-4 页 的 RVCT 在 目 标 未 知 情 况 下 的 缺 省 行 为 ;<br />

• 第 2-10 页 的 调 整 C 库 使 其 适 应 目 标 硬 件 ;<br />

• 第 2-13 页 的 调 整 映 象 存 储 器 映 射 以 适 应 目 标 硬 件 ;<br />

• 第 2-23 页 的 复 位 和 初 始 化 ;<br />

• 第 2-33 页 的 进 一 步 的 存 储 器 映 射 考 虑 事 项 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 2-1


嵌 入 式 软 件 开 发<br />

2.1 关 于 嵌 入 式 软 件 开 发<br />

多 数 嵌 入 式 应 用 程 序 最 初 都 是 在 原 型 环 境 下 开 发 的 , 原 型 环 境 的 资 源 与 最 终 产<br />

品 环 境 是 有 差 异 的 。 因 此 , 考 虑 将 嵌 入 式 应 用 程 序 从 其 所 依 赖 的 开 发 工 具 或 调 试<br />

环 境 移 植 到 在 目 标 硬 件 上 独 立 运 行 的 系 统 所 涉 及 的 过 程 , 就 是 非 常 重 要 的 。<br />

使 用 RVCT 开 发 嵌 入 式 软 件 时 , 必 须 考 虑 以 下 以 下 方 面 :<br />

• C 库 如 何 使 用 硬 件 。<br />

• 某 些 C 库 的 功 能 通 过 使 用 调 试 环 境 资 源 来 得 以 实 现 。 如 果 使 用 了 此 类 资 源 ,<br />

必 须 利 用 目 标 硬 件 重 新 实 现 这 些 功 能 。<br />

• RVCT 并 不 了 解 任 何 给 定 目 标 的 存 储 器 映 射 方 面 的 信 息 。 必 须 使 映 象 存 储<br />

器 映 射 适 合 目 标 硬 件 存 储 器 的 布 局 。<br />

• 嵌 入 式 应 用 程 序 在 主 应 用 程 序 可 以 运 行 前 必 须 须 执 行 一 些 初 始 化 工 作 。 一<br />

个 完 整 的 初 始 化 进 程 需 要 您 实 现 的 代 码 和 RVCT C 库 初 始 化 例 程 。<br />

2.1.1 示 例 代 码<br />

为 说 明 本 章 包 括 的 主 题 , 提 供 了 相 关 的 项 目 示 例 。 本 章 所 描 述 的 Dhrystone 编 译<br />

代 码 位 于 Examples_directory\emb_sw_dev 目 录 下 。 每 个 编 译 代 码 对 应 一 个 独 立 的<br />

目 录 , 并 提 供 了 本 章 后 续 节 内 所 讨 论 技 术 的 示 例 。 有 关 每 个 编 译 代 码 的 特 殊 信<br />

息 , 可 在 “ 示 例 ” 代 码 各 内 节 找 到 。<br />

Dhrystone 基 准 程 序 为 项 目 示 例 提 供 了 代 码 基 础 。 选 择 Dhrystone 是 因 为 用 它 能<br />

举 例 说 明 本 章 描 述 的 很 多 概 念 。<br />

项 目 示 例 是 为 运 行 在 <strong>ARM</strong> Integrator 开 发 平 台 上 而 编 写 的 。 但 是 , 示 例 所 说 明 的<br />

原 理 适 用 于 所 有 目 标 硬 件 。<br />

备 注<br />

本 章 的 重 点 并 不 特 别 放 在 Dhrystone 程 序 上 , 而 重 点 在 于 使 其 能 在 完 全 独 立 的 系<br />

统 上 运 行 所 要 采 取 的 步 骤 上 。 有 关 Dhrystone 作 为 一 种 基 准 工 具 更 进 一 步 的 讨<br />

论 , 请 参 阅 “ 应 用 程 序 注 释 ” 的 第 93 条 - 以 <strong>ARM</strong>ulator 为 基 准 。 您 可 在<br />

http://www.arm.com <strong>ARM</strong> 网 站 的 “ 文 档 ” (Documentation) 区 找 到 <strong>ARM</strong> 应 用 程 序<br />

注 释 。<br />

2-2 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


嵌 入 式 软 件 开 发<br />

在 Integrator 平 台 上 运 行 Dhrystone 编 译 代 码<br />

要 在 Integrator 平 台 上 运 行 本 章 介 绍 的 Dhrystone 编 译 代 码 , 必 须 :<br />

• 执 行 ROM/RAM 重 新 映 射 。 为 此 , 通 过 接 通 开 关 1 和 4 来 运 行 Boot Monitor,<br />

然 后 复 位 板 卡 。<br />

• 将 top_of_memory 设 置 为 0x40000 或 安 装 一 个 DIMM 存 储 器 模 块 。 如 果 没 有<br />

这 样 做 , 默 认 为 0x80000 的 栈 可 能 不 会 在 有 效 的 存 储 器 中 。<br />

例 如 , 要 在 <strong>RealView</strong> Debugger 中 设 置 存 储 器 的 顶 端 地 址 , 打 开 连 接 的<br />

[Connection Properties]。 在 Advanced_<strong>Information</strong>\Default\<strong>ARM</strong>_config 组 中 ,<br />

将 Top_memory 设 置 成 需 要 的 值 , 然 后 保 存 设 置 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 2-3


嵌 入 式 软 件 开 发<br />

2.2 RVCT 在 目 标 未 知 情 况 下 的 缺 省 行 为<br />

开 始 编 写 嵌 入 式 应 用 程 序 时 , 您 可 能 不 清 楚 目 标 硬 件 的 全 部 技 术 规 格 。 例 如 , 您<br />

可 能 不 知 道 目 标 外 围 设 备 、 存 储 器 映 射 甚 至 处 理 器 本 身 的 详 细 信 息 。<br />

为 在 了 解 这 些 详 细 信 息 前 能 够 继 续 软 件 的 开 发 ,RVCT 工 具 有 默 认 的 操 作 , 使 您<br />

能 立 即 编 译 和 调 试 应 用 程 序 代 码 。 了 解 这 一 默 认 操 作 非 常 有 用 , 这 样 您 会 重 视 从<br />

默 认 的 编 译 代 码 移 植 到 完 全 独 立 的 应 用 程 序 所 必 须 的 步 骤 。<br />

2.2.1 半 主 机<br />

在 RVCT C 库 中 , 对 某 些 ISO C 功 能 的 支 持 由 主 机 调 试 环 境 提 供 。 提 供 该 功 能 的<br />

机 制 被 称 为 半 主 机 。<br />

半 主 机 由 一 组 已 定 义 的 软 件 中 断 操 作 来 实 现 。 执 行 半 主 机 SWI 时 , 调 试 代 理 程<br />

序 将 其 识 别 出 并 暂 时 地 停 止 程 序 的 执 行 。 在 代 码 恢 复 执 行 之 前 , 由 调 试 代 理 程 序<br />

处 理 半 主 机 操 作 。 因 此 , 由 主 机 本 身 执 行 的 任 务 对 该 程 序 来 说 是 透 明 的 。<br />

图 2-1 说 明 了 一 个 半 主 机 操 作 的 示 例 , 该 示 例 将 一 字 符 串 打 印 输 出 到 调 试 器 控<br />

制 台 。<br />

图 2-1 半 主 机 操 作 示 例<br />

2-4 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


嵌 入 式 软 件 开 发<br />

备 注<br />

有 关 半 主 机 的 详 情 , 请 参 阅 <strong>RealView</strong> 编 译 工 具 2.0 版 编 译 程 序 和 库 指 南 中 的 半<br />

主 机 一 章 。<br />

2.2.2 C 库 结 构<br />

从 概 念 上 来 讲 ,C 库 可 被 化 分 成 两 类 函 数 , 一 类 为 ISO C 语 言 的 规 范 部 分 , 另 一<br />

类 为 ISO C 语 言 规 范 提 供 支 持 。 图 示 请 见 图 2-2。<br />

图 2-2 C 库 结 构<br />

对 部 分 ISO C 功 能 的 支 持 是 由 主 机 调 试 环 境 , 在 支 持 函 数 的 设 备 驱 动 程 序 级 别<br />

提 供 的 。<br />

例 如 , RVCT C 库 通 过 写 入 调 试 器 控 制 台 窗 口 来 实 现 ISO C printf() 系 列 函 数 。<br />

通 过 调 用 __sys_write() 来 提 供 该 功 能 。 这 是 一 个 执 行 半 主 机 SWI 的 支 持 函 数 ,<br />

使 字 符 串 被 写 入 到 控 制 台 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 2-5


嵌 入 式 软 件 开 发<br />

2.2.3 默 认 存 储 器 映 射<br />

对 于 没 有 描 述 存 储 器 映 射 的 映 象 ,RVCT 根 据 默 认 存 储 器 映 射 放 置 代 码 和 数 据 ,<br />

如 图 2-3 所 示 。<br />

以 下 是 对 默 认 存 储 器 映 射 的 说 明 :<br />

图 2-3 默 认 存 储 器 映 射<br />

• 链 接 映 象 , 在 地 址 0x8000 加 载 并 运 行 。 首 先 放 置 所 有 的 RO ( 只 读 ) 段 ,<br />

其 次 是 RW ( 读 写 ) 段 , 然 后 是 ZI ( 零 初 始 化 ) 段 。<br />

• 堆 直 接 从 ZI 段 的 顶 端 地 址 算 起 , 因 此 , 其 准 确 位 置 在 链 接 时 决 定 。<br />

• 栈 的 基 本 位 置 在 应 用 程 序 启 动 过 程 中 由 半 主 机 操 作 提 供 。 该 半 主 机 操 作 的<br />

返 回 值 取 决 于 调 试 环 境 :<br />

• <strong>ARM</strong>ulator 返 回 在 配 置 文 件 peripherals.ami 中 设 定 的 值 。 默 认 值 是<br />

0x08000000。<br />

• Multi-ICE 返 回 调 试 器 内 部 变 量 top_of_memory 的 值 。 默 认 值 是 0x00080000。<br />

2-6 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


嵌 入 式 软 件 开 发<br />

2.2.4 链 接 程 序 放 置 规 则<br />

链 接 程 序 遵 守 一 组 规 则 , 如 图 2-4 所 示 , 以 决 定 代 码 和 数 据 位 于 存 储 器 中 的 什 么<br />

位 置 。<br />

图 2-4 链 接 程 序 放 置 规 则<br />

映 象 首 先 按 属 性 组 织 :RO 段 在 最 低 的 存 储 器 地 址 , 其 次 是 RW 段 , 然 后 是 ZI<br />

段 。 每 一 种 属 性 中 , 代 码 在 数 据 之 前 。<br />

从 那 开 始 , 链 接 程 序 按 名 称 的 字 母 顺 序 放 置 输 入 段 。 输 入 段 名 称 和 汇 编 程 序 AREA<br />

命 令 一 致 。<br />

在 输 入 段 中 , 独 立 对 象 的 代 码 和 数 据 , 按 照 对 象 文 件 在 链 接 程 序 命 令 行 中 被 指 定<br />

的 顺 序 放 置 。<br />

要 精 确 放 置 代 码 和 数 据 ,<strong>ARM</strong> Limited 建 议 不 要 过 分 依 靠 这 些 规 则 。 相 反 , 必 须<br />

使 用 分 散 加 载 机 制 来 完 全 控 制 代 码 和 数 据 的 放 置 。 请 参 阅 第 2-13 页 的 调 整 映 象<br />

存 储 器 映 射 以 适 应 目 标 硬 件 。<br />

备 注<br />

有 关 放 置 规 则 和 分 散 加 载 的 详 细 说 明 , 请 参 阅 <strong>RealView</strong> 编 译 工 具 2.0 版 链 接 程 序<br />

和 实 用 程 序 指 南 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 2-7


嵌 入 式 软 件 开 发<br />

2.2.5 应 用 程 序 启 动<br />

多 数 嵌 入 式 系 统 中 , 执 行 主 任 务 前 , 执 行 初 始 化 序 列 来 设 置 系 统 。<br />

默 认 的 RVCT 初 始 化 序 列 如 图 2-5 所 示 。<br />

图 2-5 默 认 的 RVCT 初 始 化 序 列<br />

在 较 高 层 , 初 始 化 序 列 可 分 成 三 个 功 能 块 。 __main 直 接 跳 转 到 __scatterload。<br />

__scatterload 负 责 建 立 运 行 时 的 映 像 存 储 器 映 射 , 而 __rt_entry( 运 行 时 的 入 口 )<br />

则 负 责 初 始 化 C 库 。<br />

__scatterload 执 行 代 码 和 数 据 复 制 以 及 ZI 数 据 的 清 零 。 对 于 ZI 数 据 的 清 零 和 未<br />

改 变 的 RW 数 据 来 说 , 这 一 步 总 是 要 做 的 。<br />

__scatterload 跳 转 到 __rt_entry。 它 设 置 应 用 程 序 的 栈 和 堆 , 初 始 化 库 函 数 及 其<br />

静 态 数 据 , 并 调 用 任 何 全 局 声 明 的 对 象 的 构 造 函 数 ( 仅 C++)。<br />

2-8 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


嵌 入 式 软 件 开 发<br />

然 后 __rt_entry 跳 转 到 应 用 程 序 入 口 main()。 主 应 用 程 序 的 结 束 执 行 时 ,<br />

__rt_entry 将 库 关 闭 , 然 后 把 控 制 权 交 还 给 调 试 器 。<br />

RVCT 中 , 函 数 标 签 main() 有 一 个 特 殊 含 意 。main() 函 数 的 存 在 强 制 链 接 程 序 链<br />

接 到 __main 和 __rt_entry 中 的 初 始 化 代 码 。 没 有 main() 函 数 , 就 不 会 链 接 到 初 始<br />

化 进 程 , 那 么 一 些 标 准 C 库 功 能 就 不 会 得 到 支 持 。<br />

2.2.6 编 译 代 码 1 的 示 例 代 码<br />

编 译 代 码 1 是 Dhrystone Benchmark 的 默 认 编 译 版 本 。 因 此 , 它 遵 从 本 节 所 介 绍<br />

的 RVCT 默 认 操 作 。 请 参 阅 第 2-3 页 的 在 Integrator 平 台 上 运 行 Dhrystone 编 译<br />

代 码 和 Examples_directory\emb_sw_dev\build1 中 的 编 译 代 码 示 例 文 件 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 2-9


嵌 入 式 软 件 开 发<br />

2.3 调 整 C 库 使 其 适 应 目 标 硬 件<br />

默 认 情 况 下 ,C 库 利 用 半 主 机 来 提 供 设 备 驱 动 程 序 级 的 功 能 , 使 得 主 机 能 够 用 作<br />

输 入 和 输 出 设 备 。 这 种 机 制 很 有 用 , 因 为 开 发 硬 件 经 常 没 有 最 终 系 统 的 所 有 输 入<br />

和 输 出 设 备 。<br />

2.3.1 C 库 的 重 新 目 标 化<br />

您 可 建 立 属 于 自 己 的 C 库 函 数 实 现 版 本 , 它 能 充 分 利 用 目 标 硬 件 , 并 自 动 链 接<br />

到 支 持 您 C 库 实 现 版 本 的 映 象 。 该 过 程 称 为 C 库 的 重 新 目 标 化 , 如 图 2-6 所 示 。<br />

图 2-6 C 库 的 重 新 目 标 化<br />

例 如 ,fputc() 函 数 将 结 果 写 入 调 试 器 控 制 台 , 您 可 能 有 个 外 围 I/O 设 备 ( 如<br />

UART), 您 想 要 重 新 实 现 该 函 数 , 将 结 果 输 出 到 UART。 由 于 fputc() 的 实 现 链<br />

接 最 终 的 映 象 , 整 个 printf() 系 列 函 数 打 印 输 出 到 UART。<br />

fputc() 实 现 的 一 个 例 子 如 第 2-11 页 的 示 例 2-1 所 示 。<br />

该 示 例 将 fputc() 的 输 入 字 符 参 数 重 新 指 向 一 连 续 输 出 函 数 sendchar(), 而 这 是<br />

假 定 在 一 个 独 立 的 源 文 件 中 实 现 的 。 这 样 , fputc() 在 依 目 标 而 定 的 输 出 和 C 库<br />

标 准 输 出 函 数 之 间 充 当 一 个 抽 象 层 。<br />

2-10 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


嵌 入 式 软 件 开 发<br />

示 例 2-1 fputc() 的 实 现<br />

extern void sendchar(char *ch);<br />

int fputc(int ch, FILE *f)<br />

{ /* e.g. write a character to an UART */<br />

char tempch = ch;<br />

sendchar(&tempch);<br />

return ch;<br />

}<br />

2.3.2 避 免 C 库 半 主 机<br />

在 一 独 立 应 用 程 序 中 , 您 不 太 可 能 支 持 半 主 机 SWI 操 作 。 因 此 , 必 须 确 保 您 的<br />

应 用 程 序 中 没 有 链 接 C 库 半 主 机 函 数 。<br />

为 确 保 没 有 从 C 库 链 接 使 用 半 主 机 SWI 的 函 数 , 必 须 引 入 符 号<br />

__use_no_semihosting_swi。 可 在 您 项 目 的 任 何 C 或 汇 编 语 言 源 文 件 中 执 行 此 操<br />

作 , 如 下 所 述 :<br />

• 在 C 模 块 中 , 使 用 #pragma 命 令 :<br />

#pragma import(__use_no_semihosting_swi)<br />

• 在 汇 编 语 言 模 块 中 , 使 用 IMPORT 命 令 :<br />

IMPORT __use_no_semihosting_swi<br />

如 果 仍 然 链 接 了 使 用 半 主 机 SWI 的 函 数 , 链 接 程 序 会 报 告 下 列 错 误 :<br />

Error : L6200E: Symbol __semihosting_swi_guard multiply defined (by use_semi.o<br />

and use_no_semi.o).<br />

为 找 出 这 些 函 数 , 请 使 用 -verbose 选 项 链 接 。 在 输 出 结 果 中 , C 库 函 数 被 标 以<br />

如 __I_use_semihosting_swi 的 标 记 。<br />

Loading member sys_exit.o from c_a__un.l.<br />

definition: _sys_exit<br />

reference : __I_use_semihosting_swi<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 2-11


嵌 入 式 软 件 开 发<br />

必 须 为 这 些 函 数 提 供 您 自 己 的 实 现 方 法 。<br />

备 注<br />

链 接 程 序 不 报 告 您 应 用 程 序 代 码 中 的 任 何 使 用 半 主 机 SWI 的 函 数 。 仅 当 从 C 库<br />

链 接 了 使 用 半 主 机 SWI 的 函 数 时 才 发 生 错 误 。<br />

使 用 半 主 机 SWI 的 C 库 函 数 完 整 清 单 可 参 见 <strong>RealView</strong> 编 译 工 具 2.0 版 编 译 程 序<br />

和 库 指 南 。<br />

2.3.3 编 译 代 码 2 的 示 例 代 码<br />

编 译 代 码 2 的 示 例 中 使 用 了 Integrator 平 台 硬 件 处 理 时 钟 和 字 符 串 I/O。 请 参 见<br />

Examples_directory\emb_sw_dev\build2 中 的 示 例 编 译 文 件 。<br />

对 编 译 代 码 1 示 例 项 目 作 了 如 下 更 改 :<br />

C 库 的 重 新 目 标 化<br />

增 加 了 ISO C 函 数 的 重 新 目 标 化 层 。 这 包 括 标 准 的 输 入 / 输 出 功 能 、<br />

时 钟 功 能 及 其 它 一 些 出 错 信 号 通 知 以 及 程 序 退 出 。<br />

依 赖 于 目 标 的 设 备 驱 动 程 序<br />

增 加 了 直 接 与 目 标 硬 件 外 设 交 互 的 设 备 驱 动 程 序 层 。<br />

请 参 阅 第 2-3 页 的 在 Integrator 平 台 上 运 行 Dhrystone 编 译 代 码 。<br />

本 项 目 中 没 有 引 入 符 号 __use_no_semihosting_swi。 这 是 因 为 半 主 机 SWI 是 在 C<br />

库 初 始 化 过 程 中 执 行 的 , 以 设 置 应 用 程 序 堆 和 栈 的 位 置 。 有 关 重 新 目 标 化 栈 和 堆<br />

设 置 的 详 细 说 明 , 请 参 阅 第 2-18 页 的 放 置 栈 和 堆 。<br />

备 注<br />

要 查 看 输 出 结 果 , 串 行 接 口 A 必 须 连 接 一 个 终 端 或 终 端 模 拟 程 序 ( 如 超 级 终<br />

端 )。 该 串 行 接 口 必 须 设 置 为 38,400 波 特 、 无 奇 偶 校 验 、 一 个 停 止 位 和 无 流 控<br />

制 。 该 终 端 必 须 配 置 为 向 引 入 的 行 末 尾 添 加 换 行 , 并 在 本 地 显 示 键 入 的 字 符 。<br />

2-12 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


嵌 入 式 软 件 开 发<br />

2.4 调 整 映 象 存 储 器 映 射 以 适 应 目 标 硬 件<br />

在 最 终 的 嵌 入 式 系 统 中 , 没 有 半 主 机 功 能 , 您 不 太 可 能 使 用 RVCT 提 供 的 默 认<br />

存 储 器 映 射 。 目 标 硬 件 通 常 有 几 个 位 于 不 同 地 址 范 围 的 存 储 设 备 。 为 了 充 分 利 用<br />

这 些 设 备 , 加 载 和 运 行 时 必 须 有 分 开 的 存 储 器 视 图 。<br />

2.4.1 分 散 加 载<br />

分 散 加 载 能 够 将 加 载 和 运 行 时 存 储 器 中 的 代 码 和 数 据 描 述 在 被 称 为 分 散 加 载 描<br />

述 文 件 的 一 个 文 本 描 述 文 件 中 。 在 命 令 行 使 用 -scatter 选 项 , 该 项 文 件 被 传 递<br />

至 链 接 程 序 。 例 如 :<br />

armlink -scatter scat.scf file1.o file2.o<br />

分 散 加 载 描 述 文 件 根 据 寻 址 的 存 储 器 区 域 , 为 链 接 程 序 描 述 了 加 载 时 和 运 行 时<br />

代 码 和 数 据 应 在 的 位 置 。<br />

分 散 加 载 区 域<br />

分 散 加 载 区 域 分 为 两 类 :<br />

• 加 载 区 , 包 含 应 用 程 序 复 位 和 加 载 时 的 代 码 和 数 据 。<br />

• 执 行 区 , 包 含 应 用 程 序 执 行 时 的 代 码 和 数 据 。 应 用 程 序 启 动 过 程 中 , 从 每<br />

个 加 载 区 可 创 建 一 个 或 多 个 执 行 区 。<br />

映 象 中 所 有 的 代 码 和 数 据 准 确 地 分 为 一 个 加 载 区 和 一 个 执 行 区 。<br />

启 动 过 程 中 ,__main 中 的 C 库 初 始 化 代 码 实 现 了 必 要 的 代 码 和 数 据 复 制 和 清 零 ,<br />

以 从 加 载 视 图 转 为 执 行 视 图 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 2-13


嵌 入 式 软 件 开 发<br />

2.4.2 分 散 加 载 描 述 文 件 语 法<br />

分 散 加 载 描 述 文 件 语 法 反 映 了 分 散 加 载 本 身 所 提 供 的 功 能 。 图 2-7 说 明 了 文 件<br />

语 法 。<br />

区 域 由 头 标 记 定 义 , 头 标 记 ( 至 少 ) 包 括 一 个 区 名 和 一 个 起 始 地 址 。 可 以 选 择<br />

性 地 增 加 最 大 长 度 和 其 它 属 性 。<br />

区 域 中 的 内 容 取 决 于 区 域 的 类 型 :<br />

图 2-7 分 散 加 载 描 述 文 件 语 法<br />

• 加 载 区 必 须 至 少 包 含 一 个 执 行 区 。 在 实 际 操 作 中 , 每 个 加 载 区 通 常 包 含 几<br />

个 执 行 区 。<br />

• 执 行 区 须 至 少 要 包 含 一 个 代 码 或 数 据 段 , 但 由 EMPTY 属 性 声 明 的 区 域 除 外<br />

( 请 参 阅 第 2-37 页 的 使 用 分 散 文 件 的 EMPTY 属 性 )。 非 EMPTY 声 明 的 区 域<br />

通 常 包 含 源 或 库 目 标 文 件 。 可 用 通 配 符 (*) 语 法 来 为 分 散 加 载 描 述 文 件 中<br />

未 指 定 的 给 定 属 性 的 所 有 段 分 组 。<br />

备 注<br />

有 关 分 散 加 载 描 述 文 件 语 法 的 详 细 说 明 , 请 参 阅 <strong>RealView</strong> 编 译 工 具 2.0 版 链 接 程<br />

序 和 实 用 程 序 指 南 。<br />

2-14 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


嵌 入 式 软 件 开 发<br />

2.4.3 分 散 加 载 描 述 文 件 示 例<br />

图 2-8 说 明 了 分 散 加 载 的 一 个 简 单 例 子 。<br />

该 示 例 有 一 个 包 括 从 地 址 零 开 始 的 所 有 代 码 和 数 据 的 加 载 区 。 从 此 加 载 区 生 成<br />

两 个 执 行 区 。 一 个 包 含 了 所 有 的 RO 代 码 和 数 据 , 在 它 被 加 载 的 同 一 地 址 处 执<br />

行 。 另 一 个 在 地 址 0x10000 处 , 它 包 含 了 所 有 的 RW 和 ZI 数 据 。<br />

示 例 2-2 说 明 了 描 述 上 述 存 储 器 映 射 的 描 述 文 件 。<br />

图 2-8 简 单 分 散 加 载 示 例<br />

示 例 2-2 简 单 分 散 加 载 描 述 文 件<br />

ROM_LOAD 0x0000 0x4000<br />

{<br />

ROM_EXEC 0x0000 0x4000; Root region<br />

{<br />

* (+RO); All code and constant data<br />

}<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 2-15


嵌 入 式 软 件 开 发<br />

}<br />

RAM 0x10000 0x8000<br />

{<br />

* (+RW, +ZI); All non-constant data<br />

}<br />

2.4.4 在 分 散 加 载 描 述 文 件 放 置 对 象<br />

对 多 数 映 象 来 说 , 您 可 控 制 特 定 代 码 和 数 据 段 的 放 置 , 而 不 是 象 上 例 中 将 所 有 的<br />

属 性 组 合 在 一 起 。 这 可 通 过 在 描 述 文 件 中 直 接 指 定 单 个 对 象 来 完 成 , 而 不 是 仅 仅<br />

依 靠 通 配 符 语 法 。<br />

备 注<br />

描 述 文 件 中 执 行 区 对 象 的 顺 序 不 影 响 其 在 输 出 映 象 的 顺 序 。 第 2-7 页 的 链 接 程 序<br />

放 置 规 则 中 说 明 的 链 接 程 序 放 置 规 则 适 用 于 每 个 执 行 区 。<br />

要 忽 略 标 准 链 接 程 序 放 置 规 则 , 可 使 用 +FIRST 和 +LAST 分 散 加 载 命 令 。 示 例 2-3<br />

说 明 了 一 个 在 执 行 区 开 始 放 置 向 量 表 的 分 散 加 载 描 述 文 件 。 在 该 例 中 ,vectors.o<br />

中 的 Vect 区 放 置 在 地 址 0x0000 处 。 有 关 在 分 散 加 载 描 述 文 件 中 放 置 对 象 的 详 细<br />

说 明 , 请 参 阅 <strong>RealView</strong> 编 译 工 具 2.0 版 链 接 程 序 和 实 用 程 序 指 南 。<br />

示 例 2-3 放 置 段<br />

ROM_LOAD 0x0000 0x4000<br />

{<br />

ROM_EXEC 0x0000 0x4000<br />

{<br />

vectors.o (Vect, +FIRST)<br />

* (+RO)<br />

}<br />

; more exec regions…<br />

}<br />

2-16 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


嵌 入 式 软 件 开 发<br />

2.4.5 根 区<br />

根 区 是 加 载 地 址 和 其 执 行 地 址 相 同 的 执 行 区 。 每 一 个 分 散 加 载 描 述 文 件 必 须 至<br />

少 要 有 一 个 根 区 。<br />

对 分 散 加 载 的 一 个 限 制 就 是 , 负 责 创 建 执 行 区 的 代 码 和 数 据 不 能 将 其 本 身 复 制<br />

到 另 一 位 置 , 例 如 代 码 和 数 据 的 复 制 和 清 零 。 因 此 , 根 区 中 必 须 包 含 以 下 段 。<br />

• __main.o, 包 含 复 制 代 码 和 数 据 的 代 码<br />

• Region$$Table 和 ZISection$$Table 段 , 包 含 要 复 制 代 码 和 数 据 的 地 址 。<br />

由 于 这 些 段 为 只 读 属 性 , 它 们 靠 通 配 符 * (+RO) 语 法 分 组 。 因 此 , 如 果 在 非 根 区<br />

中 指 定 了 * (+RO), 必 须 在 根 区 中 显 式 地 声 明 这 些 段 。 如 示 例 2-4 所 示 。<br />

示 例 2-4 指 定 根 区<br />

ROM_LOAD 0x0000 0x4000<br />

{<br />

ROM_EXEC 0x0000 0x4000 ; root region<br />

{<br />

__main.o (+RO) ; copying code<br />

* (Region$$Table) ; RO/RW addresses to copy<br />

* (ZISection$$Table) ; ZI addresses to zero<br />

}<br />

RAM 0x10000 0x8000<br />

{<br />

* (+RO) ; all other RO sections<br />

* (+RW, +ZI) ; all RW and ZI sections<br />

}<br />

}<br />

如 果 根 区 中 没 有 包 含 __main.o、Region$$Table 和 ZISection$$Table, 将 使 链 接 程 序<br />

产 生 下 列 错 误 信 息 :<br />

Error : L6202E: Section Region$$Table cannot be assigned to a non-root region.<br />

Error: L6202E: Section ZISection$$Table cannot be assigned to a non-root<br />

region.<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 2-17


嵌 入 式 软 件 开 发<br />

2.4.6 放 置 栈 和 堆<br />

分 散 加 载 为 映 象 中 的 代 码 和 静 态 分 配 数 据 提 供 了 一 种 放 置 方 法 。 本 节 介 绍 了 如<br />

何 放 置 应 用 程 序 的 堆 和 栈 。<br />

应 用 程 序 的 堆 和 栈 是 在 C 库 初 始 化 过 程 中 建 立 的 。 可 通 过 重 新 目 标 化 负 责 建 立<br />

堆 和 栈 的 例 程 来 调 整 堆 和 栈 的 放 置 。 在 RVCT C 库 中 , 该 例 程 是<br />

__user_initial_stackheap()。<br />

图 2-9 说 明 了 带 有 重 新 目 标 化 __user_initial_stackheap() 的 C 库 初 始 化 过 程 。<br />

图 2-9 Retargeting __user_initial_stackheap()<br />

__user_initial_stackheap() 可 用 C 或 <strong>ARM</strong> 汇 编 语 言 来 编 写 。 它 必 须 返 回 以 下<br />

参 数 :<br />

• r0 中 的 堆 基 址 ;<br />

• r1 中 的 栈 基 址 ;<br />

• r2 中 的 堆 限 制 ( 如 有 必 要 );<br />

• r3 中 的 栈 限 制 ( 如 有 必 要 )。<br />

2-18 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


嵌 入 式 软 件 开 发<br />

如 果 使 用 分 散 加 载 方 法 加 载 您 的 映 象 , 必 须 重 新 实 现<br />

__user_initial_stackheap()。 否 则 , 链 接 程 序 产 生 如 下 错 误 :<br />

Error : L6218E: Undefined symbol Image$$ZI$$Limit (referred from<br />

sys_stackheap.o)<br />

2.4.7 运 行 时 存 储 器 模 块<br />

RVCT 提 供 了 两 种 可 能 用 到 的 运 行 时 存 储 器 模 型 :<br />

• 单 区 模 型 为 默 认 模 块 ;<br />

• 第 2-20 页 的 双 区 模 型 。<br />

在 两 种 运 行 时 存 储 器 模 型 中 , 默 认 情 况 下 不 检 查 栈 的 增 长 。 可 通 过 使 用 编 译 程 序<br />

选 项 --apcs /swst 编 译 所 有 的 模 块 来 启 用 映 象 中 的 软 件 栈 检 查 。 如 果 使 用 双 区 模<br />

型 , 在 实 现 __user_initial_stackheap() 时 , 还 必 须 指 定 栈 限 制 。<br />

备 注<br />

启 用 软 件 栈 检 查 增 加 了 代 码 的 实 际 大 小 和 执 行 开 销 , 因 为 必 须 在 每 一 次 函 数 调<br />

用 时 检 查 栈 指 针 的 值 , 看 其 是 否 在 栈 限 制 内 。 它 也 使 用 r10 寄 存 器 , 因 此 , 通 常<br />

建 议 不 要 在 嵌 入 式 系 统 中 使 用 。<br />

两 个 例 子 均 适 用 于 Integrator 系 统 。<br />

单 区 模 型<br />

默 认 情 况 下 为 单 区 模 型 , 应 用 程 序 的 堆 和 栈 在 同 一 存 储 器 区 中 互 相 朝 向 对 方 增<br />

长 。 在 此 情 况 下 , 分 配 新 的 堆 空 间 时 ( 即 调 用 malloc() 时 ), 对 照 栈 指 针 的 值 检<br />

查 堆 。<br />

示 例 2-5 和 第 2-20 页 的 图 2-10 说 明 了 __user_initial_stackheap() 实 现 简 单 的 单<br />

区 模 型 的 一 个 示 例 , 其 中 栈 从 地 址 0x40000 向 下 增 长 , 堆 从 地 址 0x20000 向 上 增<br />

长 。 例 程 将 相 应 的 值 加 载 到 寄 存 器 r0 和 r1, 然 后 返 回 。r2 和 r3 保 持 不 变 , 因 为<br />

在 单 区 模 型 中 不 使 用 堆 限 制 和 栈 限 制 。<br />

示 例 2-5 单 区 模 型 例 程<br />

EXPORT __user_initial_stackheap<br />

__user_initial_stackheap<br />

LDR r0, =0x20000 ;HB<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 2-19


嵌 入 式 软 件 开 发<br />

LDR r1, =0x40000 ;SB<br />

; r2 not used (HL)<br />

; r3 not used (SL)<br />

MOV pc, lr<br />

图 2-10 单 区 模 型<br />

双 区 模 型<br />

在 您 的 系 统 设 计 中 , 可 能 会 需 要 到 将 堆 和 栈 分 别 放 置 在 存 储 器 不 同 的 区 中 。 例<br />

如 , 可 能 会 保 留 一 小 块 高 速 RAM 仅 供 栈 使 用 。 要 通 知 RVCT 您 想 使 用 双 区 模<br />

型 , 必 须 使 用 汇 编 命 令 IMPORT 引 入 符 号 __use_two_region_memory。 然 后 , 对 照<br />

__user_initial_stackheap() 建 立 的 专 用 堆 限 制 来 检 查 堆 。<br />

示 例 2-6 和 第 2-21 页 的 图 2-11 说 明 了 一 个 实 现 双 区 模 型 的 示 例 。 栈 从 0x40000 向<br />

0x20000 的 限 制 向 下 增 长 。 为 使 用 该 栈 限 制 , 所 有 使 用 此 实 现 的 模 块 必 须 进 行 编<br />

译 以 便 进 行 软 件 栈 检 查 。 堆 从 0x28000000 到 0x28080000 向 上 增 长 。<br />

示 例 2-6 双 区 模 型 例 程<br />

IMPORT __use_two_region_memory<br />

EXPORT __user_initial_stackheap<br />

__user_initial_stackheap<br />

LDR r0, =0x28000000 ;HB<br />

LDR r1, =0x40000 ;SB<br />

2-20 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


嵌 入 式 软 件 开 发<br />

LDR r2, =0x28080000 ;HL<br />

LDR r3, =0x20000 ;SL<br />

MOV pc, lr<br />

图 2-11 双 区 模 型<br />

2.4.8 编 译 代 码 3 的 示 例 代 码<br />

编 译 代 码 3 示 例 实 现 了 分 散 加 载 , 并 且 包 括 一 个 重 新 目 标 化 的<br />

__user_initial_stackheap()。 请 参 阅 Examples_directory\emb_sw_dev\build3 中 的 编<br />

译 代 码 示 例 文 件 。<br />

对 编 译 代 码 2 示 例 项 目 作 了 如 下 更 改 :<br />

分 散 加 载<br />

一 个 简 单 的 分 散 加 载 描 述 文 件 传 递 给 链 接 程 序 。<br />

重 新 目 标 化 的 __user_initial_stackheap()<br />

可 选 择 单 区 或 双 区 实 现 方 法 之 一 。 默 认 是 单 区 编 译 。 可 通 过 在 编 译<br />

步 骤 定 义 two_region 来 选 择 双 区 实 现 方 法 。<br />

避 免 C 库 的 半 主 机<br />

该 编 译 代 码 中 引 入 了 符 号 __use_no_semihosting_swi, 因 为 映 象 中 不<br />

再 有 C 库 半 主 机 函 数 存 在 。<br />

请 参 阅 第 2-3 页 的 在 Integrator 平 台 上 运 行 Dhrystone 编 译 代 码 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 2-21


嵌 入 式 软 件 开 发<br />

备 注<br />

为 避 免 对 clock() 使 用 半 主 机 , 在 Integrator 汇 编 平 台 上 , 这 一 功 能 通 过 读 取 实 时<br />

时 钟 (RTC) 来 重 新 目 标 化 。 它 有 一 秒 钟 的 影 响 , 因 而 Dhrystone 的 结 果 是 不 精 确<br />

的 。 该 机 制 在 编 译 代 码 4 中 进 行 了 改 进 。<br />

2-22 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


嵌 入 式 软 件 开 发<br />

2.5 复 位 和 初 始 化<br />

到 目 前 为 止 本 章 假 设 是 从 C 库 初 始 化 例 程 的 入 口 __main 开 始 执 行 的 。 实 际 上 ,<br />

任 何 目 标 硬 件 上 的 嵌 入 式 应 用 程 序 在 启 动 时 都 实 现 了 一 些 系 统 级 的 初 始 化 。 本<br />

节 将 对 此 予 以 详 细 说 明 。<br />

2.5.1 初 始 化 序 列<br />

图 2-12 说 明 了 一 个 适 用 于 <strong>ARM</strong> 嵌 入 式 系 统 的 可 能 的 初 始 化 序 列 。<br />

图 2-12 初 始 化 序 列<br />

图 2-12 中 的 复 位 处 理 程 序 在 系 统 启 动 时 立 即 执 行 。 进 入 主 应 用 程 序 前 , 立 即 执<br />

行 标 有 $Sub$$main() 的 代 码 块 。<br />

复 位 处 理 程 序 是 用 汇 编 语 言 写 的 短 代 码 块 , 它 在 系 统 复 位 时 执 行 。 复 位 处 理 程 序<br />

最 少 为 应 用 程 序 运 行 所 在 的 模 式 初 始 化 栈 指 针 。 对 于 具 有 局 部 存 储 器 的 内 核 , 如<br />

缓 存 、 紧 密 藕 荷 存 储 器 (TCM)、 存 储 器 管 理 单 元 (MMU) 和 存 储 器 保 护 单 元<br />

(MPU) 等 , 在 初 始 化 过 程 这 一 阶 段 必 须 完 成 某 些 配 置 。 复 位 处 理 程 序 在 执 行 之<br />

后 , 通 常 跳 转 到 __main 以 开 始 C 库 的 初 始 化 序 列 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 2-23


嵌 入 式 软 件 开 发<br />

系 统 初 始 化 的 一 些 组 成 部 分 , 如 启 用 中 断 , 通 常 是 在 C 库 初 始 化 代 码 执 行 完 成<br />

后 才 执 行 。 在 主 应 用 程 序 开 始 执 行 前 , 标 有 $Sub$$main() 的 代 码 块 立 即 执 行 这 些<br />

任 务 。<br />

有 关 初 始 化 序 列 各 个 组 成 部 分 的 详 细 说 明 , 请 参 阅 向 量 表 。<br />

2.5.2 向 量 表<br />

所 有 的 <strong>ARM</strong> 系 统 都 有 一 个 向 量 表 。 向 量 表 不 是 初 始 化 序 列 的 一 部 分 , 但 是 , 对<br />

每 个 要 处 理 的 异 常 , 它 必 须 存 在 。<br />

示 例 2-7 中 的 代 码 引 入 了 各 种 异 常 处 理 程 序 , 可 能 可 在 其 它 模 块 中 进 行 代 码 移<br />

植 。 向 量 表 是 转 到 各 种 异 常 处 理 程 序 的 跳 转 指 令 列 表 。<br />

FIQ 处 理 程 序 被 直 接 放 置 在 地 址 0x1C。 它 省 下 了 到 FIQ 处 理 程 序 的 一 次 跳 转 , 因<br />

而 优 化 了 FIQ 的 反 应 时 间 。<br />

示 例 2-7 引 入 异 常 处 理 程 序<br />

AREA Vectors, CODE, READONLY<br />

IMPORT Reset_Handler<br />

; import other exception handlers<br />

; …<br />

ENTRY<br />

B Reset_Handler<br />

B Undefined_Handler<br />

B SWI_Handler<br />

B Prefetch_Handler<br />

B Data_Handler<br />

NOP ; Reserved vector<br />

B IRQ_Handler<br />

; FIQ_Handler will follow directly<br />

END<br />

2-24 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


嵌 入 式 软 件 开 发<br />

备 注<br />

向 量 表 标 有 ENTRY 标 签 。 该 标 签 通 知 链 接 程 序 该 代 码 是 一 个 可 能 的 入 口 点 , 因 而<br />

在 链 接 时 , 不 能 从 映 象 中 将 其 清 除 。 必 须 使 用 -entry 链 接 程 序 选 项 在 可 能 的 映<br />

象 入 口 中 选 一 个 作 为 应 用 程 序 的 真 正 入 口 点 。 有 关 详 细 说 明 , 请 参 阅 <strong>RealView</strong><br />

编 译 工 具 2.0 版 编 译 程 序 和 实 用 程 序 指 南 。<br />

2.5.3 ROM/RAM 重 新 映 射<br />

必 须 考 虑 您 的 系 统 在 执 行 的 第 一 条 指 令 的 地 址 0x0000 处 是 什 么 样 的 存 储 器 。<br />

备 注<br />

本 节 假 设 <strong>ARM</strong> 内 核 开 始 在 0x0000 地 址 取 指 令 , 这 是 以 <strong>ARM</strong> 为 内 核 的 系 统 的 标<br />

准 。 但 是 , 有 些 <strong>ARM</strong> 内 核 可 通 过 配 置 从 0xFFFF0000 地 址 开 始 取 指 令 。<br />

启 动 时 ,0x0000 处 必 须 要 有 一 条 有 效 指 令 , 因 此 , 复 位 时 0x0000 地 址 必 须 为 非 易<br />

失 性 存 储 器 。<br />

一 种 实 现 方 法 就 是 将 ROM 定 位 在 0x0000。 但 是 , 这 样 配 置 有 几 个 缺 点 。 对 ROM<br />

的 存 取 速 度 通 常 较 RAM 要 慢 , 当 跳 转 到 异 常 处 理 程 序 时 , 系 统 性 能 可 能 会 大 受<br />

影 响 。 并 且 , 将 向 量 表 放 于 ROM 中 , 使 您 不 能 在 运 行 时 修 改 它 。<br />

另 一 个 解 决 方 法 如 第 2-26 页 的 图 2-13 所 示 。 ROM 位 于 地 址 0x10000, 但 是 该 存<br />

储 器 在 复 位 时 被 存 储 控 制 器 还 分 配 了 第 二 个 地 址 :0。 复 位 后 , 复 位 处 理 程 序 的<br />

代 码 跳 转 到 ROM 的 实 际 地 址 。 然 后 存 储 器 控 制 器 清 除 ROM 的 临 时 第 二 地 址 设<br />

置 , 因 而 在 地 址 0x0000 显 示 RAM。 在 __main 中 , 向 量 表 被 复 制 到 0x0000 地 址 的<br />

RAM 中 , 从 而 异 常 得 以 处 理 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 2-25


嵌 入 式 软 件 开 发<br />

图 2-13 ROM/RAM 重 新 映 射<br />

第 2-27 页 的 示 例 2-8 说 明 了 如 何 在 <strong>ARM</strong> 汇 编 模 块 中 实 现 ROM/RAM 的 重 新 映<br />

射 。 此 处 所 显 示 的 常 量 是 特 定 于 Integrator 平 台 的 , 但 是 , 同 样 的 方 法 适 用 于 用<br />

类 似 方 法 实 现 ROM/RAM 重 映 射 的 任 何 平 台 。<br />

第 一 条 指 令 是 从 ROM 临 时 地 址 (0 地 址 ) 到 实 际 ROM 的 一 条 转 移 指 令 。 可 以<br />

这 样 做 是 因 为 标 签 Instruct_2 位 于 实 际 ROM 地 址 处 。<br />

之 后 , 通 过 转 换 综 合 内 核 模 块 (Integrator Core Module) 控 制 寄 存 器 的 重 映 射 位 ,<br />

清 除 ROM 的 临 时 地 址 设 置 。<br />

该 代 码 通 常 在 系 统 复 位 后 立 即 执 行 。 重 新 映 射 必 须 在 执 行 C 库 初 始 化 代 码 前<br />

完 成 。<br />

备 注<br />

在 具 有 MMU 的 系 统 中 , 可 通 过 在 系 统 启 动 时 配 置 MMU 来 实 现 重 映 射 。<br />

2-26 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


嵌 入 式 软 件 开 发<br />

示 例 2-8 ROM/RAM 重 新 映 射<br />

; --- Integrator CM control reg<br />

CM_ctl_reg EQU 0x1000000C ; Address of CM Control Register<br />

Remap_bit EQU 0x04 ; Bit 2 is remap bit of CM_ctl<br />

ENTRY<br />

; Code execution starts here on reset<br />

; On reset, an alias of ROM is at 0x0, so jump to 'real' ROM.<br />

LDR pc, =Instruct_2<br />

Instruct_2<br />

; Remap by setting Remap bit of the CM_ctl register<br />

LDR r1, =CM_ctl_reg<br />

LDR r0, [r1]<br />

ORR r0, r0, #Remap_bit<br />

STR r0,[r1]<br />

; RAM is now at 0x0.<br />

; The exception vectors must be copied from ROM to RAM (in __main)<br />

; Reset_Handler follows on from here<br />

2.5.4 局 部 存 储 器 设 置 有 关 的 考 虑 事 项<br />

许 多 <strong>ARM</strong> 处 理 器 内 核 具 有 芯 片 级 的 存 储 器 系 统 , 如 MMU 或 MPU。 这 些 设 备<br />

通 常 是 在 系 统 启 动 过 程 中 进 行 设 置 并 启 用 的 。 因 此 , 带 有 局 部 存 储 器 系 统 的 内 核<br />

的 初 始 化 序 列 需 要 特 别 地 考 虑 。<br />

如 本 章 所 述 ,__main 中 C 库 初 始 化 代 码 负 责 建 立 映 象 在 执 行 时 的 存 储 器 映 射 。 因<br />

而 , 在 跳 转 到 __main 前 , 必 须 建 立 处 理 器 内 核 的 运 行 时 存 储 器 视 图 。 这 就 是 说 ,<br />

在 复 位 处 理 程 序 中 必 须 设 置 并 启 用 MMU 或 MPU。<br />

在 跳 转 到 __main 前 ( 通 常 在 MMU/MPU 设 置 前 ), 必 须 启 用 TCM, 因 为 在 通 常<br />

情 况 下 都 是 采 用 分 散 加 载 方 法 将 代 码 和 数 据 装 入 TCM。 必 须 注 意 , 不 必 存 取 启<br />

用 TCM 后 屏 蔽 的 存 储 器 。<br />

在 跳 转 到 __main 前 , 如 果 启 用 了 高 速 缓 存 , 可 能 还 会 遇 到 高 速 缓 存 一 致 性 的 问<br />

题 。__main 中 的 代 码 从 其 加 载 地 址 向 其 执 行 地 址 复 制 代 码 区 , 基 本 上 是 将 指 令 作<br />

为 数 据 进 行 处 理 。 结 果 , 一 些 指 令 可 放 入 数 据 高 速 缓 存 中 , 在 此 情 况 下 , 对 指 令<br />

路 径 来 说 , 它 们 是 不 可 见 的 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 2-27


嵌 入 式 软 件 开 发<br />

为 避 免 这 些 一 致 性 问 题 , 在 C 库 初 始 化 序 列 执 行 完 成 后 启 用 高 速 缓 存 。<br />

2.5.5 分 散 加 载 和 存 储 器 设 置<br />

在 一 个 内 核 的 复 位 时 存 储 器 视 图 会 改 变 的 系 统 中 , 不 论 是 通 过 ROM/RAM 重<br />

映 射 还 是 通 过 MMU 配 置 , 分 散 加 载 文 件 必 须 描 述 重 映 射 发 生 以 后 的 存 储 器 映<br />

射 关 系 。<br />

示 例 2-9 中 的 描 述 文 件 和 重 映 射 后 第 2-25 页 的 ROM/RAM 重 新 映 射 中 的 示 例 相<br />

关 。<br />

示 例 2-9<br />

ROM_LOAD 0x10000 0x8000<br />

{<br />

ROM_EXEC 0x10000 0x8000<br />

{<br />

reset_handler.o (+RO, +FIRST)<br />

…<br />

}<br />

; executed on hard reset<br />

zero<br />

}<br />

RAM 0x0000 0x4000<br />

{<br />

vectors.o (+RO, +FIRST)<br />

}<br />

…<br />

; vector table copied from ROM to RAM at<br />

加 载 区 ROM_LOAD 放 置 在 0x10000, 因 为 它 指 示 了 重 映 射 发 生 后 代 码 和 数 据 的 加 载<br />

地 址 。<br />

2-28 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


嵌 入 式 软 件 开 发<br />

2.5.6 栈 指 针 初 始 化<br />

复 位 处 理 程 序 最 少 必 须 为 应 用 程 序 所 使 用 的 任 何 执 行 模 式 的 栈 指 针 分 配 初 始 值 。<br />

在 示 例 2-10 中 , 栈 位 于 stack_base 地 址 。 该 符 号 可 以 是 个 硬 编 码 地 址 , 或 者 可<br />

以 是 在 独 立 的 汇 编 源 文 件 中 定 义 并 由 分 散 加 载 描 述 文 件 定 位 。 有 关 如 何 完 成 的<br />

详 细 信 息 , 请 参 阅 第 2-34 页 的 在 分 散 加 载 描 述 文 件 中 放 置 堆 和 栈 。<br />

该 示 例 中 为 FIQ 和 IRQ 模 式 分 配 了 256 字 节 的 栈 , 也 可 对 其 它 执 行 模 式 这 么 做 。<br />

为 了 设 置 栈 指 针 , 进 入 每 种 模 式 ( 中 断 禁 用 ) 并 为 栈 指 针 分 配 适 合 的 值 。 要 利<br />

用 软 件 栈 检 查 , 也 必 须 在 此 设 置 栈 限 制 。<br />

复 位 处 理 程 序 中 设 置 的 栈 指 针 和 栈 限 制 值 由 C 库 初 始 化 代 码 作 为 参 数 自 动 传 递<br />

给 __user_initial_stackheap()。 因 此 , 不 允 许 __user_initial_stackheap() 更 改 这<br />

些 值 。<br />

示 例 2-10 初 始 化 栈 指 针<br />

; --- Amount of memory (in bytes) allocated for stacks<br />

Len_FIQ_Stack EQU 256<br />

Len_IRQ_Stack EQU 256<br />

…<br />

Offset_FIQ_Stack EQU 0<br />

Offset_IRQ_Stack EQU Offset_FIQ_Stack + Len_FIQ_Stack<br />

…<br />

Reset_Handler<br />

; stack_base could be defined above, or located in a description file<br />

LDR r0, stack_base ;<br />

; Enter each mode in turn and set up the stack pointer<br />

MSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit<br />

SUB sp, r0, #Offset_FIQ_Stack<br />

MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit<br />

SUB sp, r0, #Offset_IRQ_Stack<br />

…<br />

; Set up stack limit if needed<br />

LDR r10, stack_limit<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 2-29


嵌 入 式 软 件 开 发<br />

示 例 2-11 说 明 了 __user_initial_stackheap() 的 一 种 实 现 , 可 以 与 第 2-29 页 的 示<br />

例 2-10 中 所 示 的 栈 指 针 设 置 配 合 使 用 。<br />

示 例 2-11<br />

IMPORT heap_base<br />

EXPORT __user_initial_stackheap()<br />

__user_initial_stackheap()<br />

; heap base could be hard coded, or placed by description file<br />

LDR r0,=heap_base<br />

; r1 contains SB value<br />

MOV pc,lr<br />

2.5.7 硬 件 初 始 化<br />

一 般 来 说 , 将 所 有 系 统 初 始 化 的 代 码 和 主 应 用 程 序 分 开 是 非 常 好 的 一 种 做 法 。 但<br />

是 , 部 分 系 统 初 始 化 过 程 , 如 启 用 高 速 缓 存 和 中 断 , 必 须 在 C 库 初 始 化 代 码 执<br />

行 完 成 后 才 能 发 生 。<br />

可 利 用 $Sub 和 $Super 函 数 包 装 符 来 有 效 地 插 入 一 个 例 程 , 该 例 程 在 进 入 主 应 用<br />

程 序 前 立 即 执 行 。 这 一 机 制 使 您 能 在 不 改 变 源 代 码 的 情 况 下 扩 展 函 数 的 功 能 。<br />

示 例 2-12 说 明 了 如 何 以 这 种 方 式 使 用 $Sub 和 $Super。 链 接 程 序 通 过 调 用<br />

$Sub$$main() 取 代 了 对 main() 函 数 的 调 用 。 从 该 处 可 调 用 启 用 高 速 缓 存 的 例 程 ,<br />

也 可 调 用 启 用 中 断 的 另 一 例 程 。<br />

通 过 调 用 $Sub$$main(), 代 码 跳 转 到 实 际 的 main()。<br />

备 注<br />

有 关 $Sub 和 $Super 的 更 多 说 明 , 请 参 阅 <strong>RealView</strong> 编 译 工 具 2.0 版 链 接 程 序 和 实<br />

用 程 序 指 南 。<br />

示 例 2-12 使 用 $Sub 和 $Super<br />

extern void $Super$$main(void);<br />

void $Sub$$main(void)<br />

{<br />

cache_enable();<br />

// enables caches<br />

2-30 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


嵌 入 式 软 件 开 发<br />

}<br />

int_enable();<br />

$Super$$main();<br />

// enables interrupts<br />

// calls original main()<br />

2.5.8 执 行 模 式 需 考 虑 的 事 项<br />

必 须 考 虑 主 应 用 程 序 要 运 行 的 模 式 。 您 的 选 择 会 影 响 如 何 实 现 系 统 的 初 始 化 。<br />

许 多 想 在 启 动 时 在 复 位 处 理 程 序 和 $Sub$$main 中 实 现 的 功 能 , 仅 能 够 在 特 权 模 式<br />

下 执 行 方 可 完 成 。 例 如 , 芯 片 级 存 储 器 操 作 及 启 用 中 断 。<br />

如 果 您 想 在 特 权 模 式 下 ( 如 超 级 用 户 (Supervisor) 模 式 ) 运 行 应 用 程 序 , 这 不 成<br />

问 题 。 请 确 保 在 退 出 复 位 处 理 程 序 前 切 换 到 适 当 的 模 式 。<br />

如 果 想 在 用 户 (User) 模 式 下 运 行 应 用 程 序 , 在 优 先 模 式 下 完 成 必 要 的 任 务 后 , 切<br />

换 到 用 户 模 式 即 可 。 这 在 Sub$$main() 中 最 可 能 发 生 。<br />

备 注<br />

__user_initial_stackheap() 必 须 设 置 应 用 程 序 模 式 栈 。 所 以 , 必 须 退 出 系 统 模 式<br />

下 的 , 使 用 用 户 模 式 寄 存 器 的 复 位 处 理 程 序 。 __user_initial_stackheap() 然 后 在<br />

系 统 模 式 下 执 行 , 因 而 , 在 进 入 用 户 模 式 时 , 应 用 程 序 的 堆 和 栈 仍 然 存 在 。<br />

2.5.9 编 译 代 码 4 示 例 代 码<br />

编 译 代 码 4 示 例 可 在 Integrator 平 台 上 独 立 运 行 。 请 参 阅<br />

Examples_directory\emb_sw_dev\build4 中 的 编 译 代 码 示 例 文 件 。<br />

对 编 译 代 码 3 示 例 项 目 作 了 如 下 更 改 :<br />

向 量 表<br />

对 项 目 增 加 了 一 个 向 量 表 , 由 分 散 加 载 描 述 文 件 放 置 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 2-31


嵌 入 式 软 件 开 发<br />

复 位 处 理 程 序<br />

init.s 中 增 加 了 复 位 处 理 程 序 。 <strong>ARM</strong>926EJ-S 编 译 代 码 中 包 含 了 分<br />

别 负 责 设 置 TCM 和 MMU 的 两 个 独 立 模 块 。 运 行 在 带 任 何 内 核 的<br />

Integrator 平 台 上 的 <strong>ARM</strong>7/TDMI 编 译 代 码 不 包 括 这 些 模 块 。 复 位<br />

后 , ROM/RAM 重 映 射 立 即 发 生 。<br />

$Sub$$main()<br />

对 于 <strong>ARM</strong>926EJ-S 编 译 代 码 , 进 入 主 应 用 程 序 前 , 在 $Sub$$main()<br />

中 启 用 高 速 缓 存 。<br />

嵌 入 式 描 述 文 件<br />

使 用 了 嵌 入 式 描 述 文 件 , 它 反 映 了 重 映 射 后 的 存 储 器 视 图 。<br />

这 些 编 译 代 码 的 编 译 文 件 生 成 了 一 个 适 合 下 载 至 地 址 0x24000000 处 的 Integrator<br />

AP 应 用 程 序 闪 存 的 二 进 制 文 件 。<br />

使 用 AP 主 板 上 的 定 时 器 实 现 精 确 的 定 时 器 。 这 产 生 一 个 IRQ, 随 安 装 一 个 处 理<br />

程 序 每 隔 1/100 秒 增 加 计 数 器 的 计 数 。<br />

2-32 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


嵌 入 式 软 件 开 发<br />

2.6 进 一 步 的 存 储 器 映 射 考 虑 事 项<br />

本 章 的 上 一 节 介 绍 了 分 散 加 载 描 述 文 件 中 代 码 和 数 据 的 放 置 , 但 是 , 其 目 标 硬 件<br />

外 设 的 位 置 和 堆 和 栈 限 制 被 假 设 为 源 文 件 或 头 文 件 中 的 硬 编 码 。 在 描 述 文 件 中<br />

定 位 所 有 与 目 标 的 存 储 器 映 射 有 关 的 信 息 是 大 有 好 处 的 , 因 此 从 源 代 码 中 删 除<br />

所 有 引 用 绝 对 地 址 的 代 码 。<br />

2.6.1 在 分 散 加 载 描 述 文 件 中 定 位 目 标 外 设<br />

按 惯 例 , 外 设 寄 存 器 的 地 址 在 项 目 源 文 件 或 头 文 件 中 是 硬 编 码 的 。 也 可 声 明 映 射<br />

到 外 设 寄 存 器 的 结 构 , 并 将 这 些 结 构 放 置 在 描 述 文 件 中 。<br />

例 如 , 目 标 可 能 会 有 一 个 带 双 存 储 器 映 射 32 位 寄 存 器 的 定 时 器 外 设 。 示 例 2-13<br />

说 明 了 映 射 到 这 些 寄 存 器 的 一 个 C 结 构 。<br />

示 例 2-13 映 射 到 外 设 寄 存 器<br />

struct {<br />

volatile unsigned ctrl; /* timer control */<br />

volatile unsigned tmr; /* timer value */<br />

} timer_regs;<br />

要 把 该 结 构 放 在 存 储 器 映 射 的 特 定 地 址 , 需 创 建 一 个 新 的 执 行 区 来 装 入 该 结 构 。<br />

示 例 2-14 说 明 的 描 述 文 件 将 timer_regs 结 构 定 位 在 0x40000000 地 址 处 。<br />

应 用 程 序 启 动 过 程 中 不 将 这 些 寄 存 器 的 内 容 初 始 化 为 零 是 非 常 重 要 的 , 因 为 这<br />

很 可 能 改 变 系 统 的 状 态 。 将 执 行 区 标 记 上 UNINIT 属 性 可 避 免 该 区 中 的 ZI 数 据 初<br />

始 化 为 零 。<br />

示 例 2-14 放 置 映 射 结 构<br />

ROM_LOAD 0x24000000 0x04000000<br />

{<br />

; …<br />

TIMER 0x40000000 UNINIT<br />

{<br />

timer_regs.o (+ZI)<br />

}<br />

; …<br />

}<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 2-33


嵌 入 式 软 件 开 发<br />

2.6.2 在 分 散 加 载 描 述 文 件 中 放 置 堆 和 栈<br />

多 数 情 况 下 , 在 描 述 文 件 中 指 定 堆 和 栈 的 位 置 是 更 可 取 的 做 法 。 它 有 两 个 主 要<br />

优 点 :<br />

• 有 关 存 储 器 映 射 的 所 有 信 息 保 存 在 一 个 文 件 中 。<br />

• 改 变 堆 和 栈 只 要 求 重 新 链 接 , 而 不 需 要 重 新 编 译 。<br />

本 节 介 绍 了 实 现 该 功 能 的 如 下 几 个 方 法 :<br />

• 显 式 放 置 符 号 , 两 种 方 法 中 最 简 单 的 方 法 ;<br />

• 第 2-35 页 的 使 用 链 接 程 序 生 成 符 号 ;<br />

• 第 2-37 页 的 使 用 分 散 文 件 的 EMPTY 属 性 。<br />

显 式 放 置 符 号<br />

第 2-29 页 的 栈 指 针 初 始 化 作 为 可 放 置 在 描 述 文 件 中 的 参 照 符 号 引 用 符 号<br />

stack_base 和 heap_base。 为 此 , 需 在 名 为 stackheap.s 的 汇 编 模 块 中 创 建 标 有<br />

stack_base 和 heap_base 的 符 号 。 对 于 双 区 存 储 器 模 型 的 堆 和 栈 限 制 也 可 执 行 同<br />

样 的 操 作 。<br />

可 在 描 述 文 件 的 各 自 执 行 区 中 定 位 每 个 符 号 , 如 示 例 2-15 所 示 。<br />

示 例 2-15 在 stackheap.s 中 显 式 地 放 置 符 号<br />

AREA stacks, DATA, NOINIT<br />

EXPORT stack_base<br />

stack_base SPACE 1<br />

AREA heap, DATA, NOINIT<br />

EXPORT heap_base<br />

heap_base SPACE 1<br />

END<br />

第 2-35 页 的 示 例 2-16 和 第 2-35 页 的 图 2-14 说 明 了 如 何 在 0x20000 放 置 堆 基 址 ,<br />

如 何 在 0x40000 放 置 栈 基 址 。 堆 基 址 和 栈 基 址 的 位 置 可 通 过 分 别 编 辑 其 执 行 区 予<br />

以 改 变 。<br />

该 方 法 的 缺 点 是 在 该 栈 区 的 上 部 占 用 SPACE (stack_base) 的 一 个 字 。<br />

2-34 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


嵌 入 式 软 件 开 发<br />

示 例 2-16 在 分 散 文 件 中 显 式 地 放 置 符 号<br />

LOAD_FLASH 0x24000000 0x04000000<br />

{<br />

; …<br />

HEAP 0x20000 UNINIT<br />

{<br />

stackheap.o (heap)<br />

}<br />

STACKS 0x40000 UNINIT<br />

{<br />

stackheap.o (stacks)<br />

}<br />

; …<br />

}<br />

图 2-14 显 式 放 置 符 号<br />

使 用 链 接 程 序 生 成 符 号<br />

该 方 法 需 要 在 目 标 文 件 中 指 定 堆 和 栈 的 大 小 。<br />

首 先 , 在 一 个 汇 编 源 文 件 中 为 堆 和 栈 定 义 一 个 适 当 大 小 的 区 域 , 例 如 ,<br />

stackheap.s, 如 第 2-36 页 的 示 例 2-17 所 示 。 使 用 SPACE 命 令 保 留 一 个 清 零 的 存<br />

储 器 块 。 设 置 NOINIT 区 域 属 性 避 免 这 一 清 零 过 程 。 开 发 过 程 中 , 可 能 会 选 择 将<br />

栈 零 初 始 化 以 最 大 化 地 使 用 栈 。 此 源 文 件 中 不 需 要 标 签 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 2-35


嵌 入 式 软 件 开 发<br />

示 例 2-17 放 置 用 于 栈 和 堆 的 段<br />

AREA stack, DATA, NOINIT<br />

SPACE 0x3000 ; Reserve stack space<br />

AREA heap, DATA, NOINIT<br />

SPACE 0x3000 ; Reserve heap space<br />

END<br />

然 后 就 可 在 分 散 加 载 描 述 文 件 的 各 自 执 行 区 中 放 置 这 些 段 , 如 示 例 2-18 所 示 。<br />

示 例 2-18 放 置 用 于 栈 和 堆 的 段<br />

LOAD_FLASH 0x24000000 0x04000000<br />

{<br />

:<br />

STACK 0x1000 UNINIT ; length = 0x3000<br />

{<br />

stackheap.o (stack) ; stack = 0x4000 to 0x1000<br />

}<br />

}<br />

HEAP 0x15000 UNINIT ; length = 0x3000<br />

{<br />

stackheap.o (heap) ; heap = 0x15000 to 0x18000<br />

}<br />

链 接 程 序 生 成 了 指 向 每 个 执 行 区 基 址 和 限 制 的 符 号 , 可 将 其 引 入 重 新 目 标 化 目<br />

标 代 码 中 供 __user_initial_stackheap() 使 用 :<br />

Image$$STACK$$ZI$$Limit = 0x4000<br />

Image$$STACK$$ZI$$Base = 0x1000<br />

Image$$HEAP$$ZI$$Base = 0x15000<br />

Image$$HEAP$$ZI$$Limit = 0x18000<br />

通 过 使 用 DCD 命 令 赋 予 这 些 值 更 有 意 义 的 名 称 可 使 该 代 码 可 读 性 更 高 , 如 第 2-37<br />

页 的 示 例 2-19 所 示 。<br />

2-36 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


嵌 入 式 软 件 开 发<br />

示 例 2-19 使 用 DCD 命 令<br />

IMPORT<br />

IMPORT<br />

IMPORT<br />

IMPORT<br />

||Image$$STACK$$ZI$$Base||<br />

||Image$$STACK$$ZI$$Limit||<br />

||Image$$HEAP$$ZI$$Base||<br />

||Image$$HEAP$$ZI$$Limit||<br />

stack_base DCD ||Image$$STACK$$ZI$$Limit|| ; = 0x4000<br />

stack_limit DCD ||Image$$STACK$$ZI$$Base|| ; = 0x1000<br />

heap_base DCD ||Image$$HEAP$$ZI$$Base|| ; = 0x15000<br />

heap_limit DCD ||Image$$HEAP$$ZI$$Limit|| ; = 0x18000<br />

可 使 用 这 些 示 例 将 堆 基 址 放 置 在 0x15000, 将 栈 基 址 放 置 在 0x1000。 然 后 , 堆 和<br />

栈 的 基 址 位 置 通 过 分 别 编 辑 其 执 行 区 可 以 很 容 易 地 改 变 。<br />

使 用 分 散 文 件 的 EMPTY 属 性<br />

该 方 法 使 用 了 链 接 程 序 的 分 散 文 件 EMPTY 属 性 。 这 将 使 得 要 定 义 的 区 域 不 包 括 目<br />

标 代 码 或 数 据 。 这 是 定 义 堆 和 栈 的 一 个 方 便 方 法 。 区 域 的 长 度 在 EMPTY 属 性 后 指<br />

定 。 对 于 存 储 器 中 向 上 增 长 的 堆 , 其 区 域 的 长 度 为 正 。 对 于 栈 , 其 长 度 被 标 为 负<br />

数 , 指 示 它 在 存 储 器 中 是 向 下 增 长 的 。 示 例 2-20 说 明 了 如 何 使 用 EMPTY 属 性 。<br />

该 方 法 的 优 点 是 堆 和 栈 的 大 小 和 位 置 是 在 一 个 地 方 定 义 的 , 即 在 分 散 文 件 中 。 您<br />

不 必 创 建 stackheap.s 文 件 。<br />

示 例 2-20 使 用 EMPTY 放 置 栈 区 和 堆 区<br />

ROM_LOAD 0x24000000 0x04000000<br />

{<br />

:<br />

HEAP 0x30000 EMPTY 0x3000<br />

{<br />

}<br />

:<br />

}<br />

STACKS 0x40000 EMPTY -0x3000<br />

{<br />

}<br />

链 接 时 , 链 接 程 序 生 成 代 表 这 些 EMPTY 区 的 符 号 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 2-37


嵌 入 式 软 件 开 发<br />

Image$$HEAP$$ZI$$Base<br />

Image$$HEAP$$ZI$$Limit<br />

Image$$STACKS$$ZI$$Base<br />

Image$$STACKS$$ZI$$Limit<br />

= 0x30000<br />

= 0x33000<br />

= 0x3D000<br />

= 0x40000<br />

然 后 , 应 用 程 序 代 码 就 可 处 理 这 些 符 号 , 如 示 例 2-21 所 示 。<br />

示 例 2-21 链 接 程 序 生 成 代 表 EMPTY 区 的 符 号<br />

IMPORT<br />

IMPORT<br />

||Image$$HEAP$$ZI$$Base||<br />

||Image$$HEAP$$ZI$$Limit||<br />

heap_base DCD ||Image$$HEAP$$ZI$$Base||<br />

heap_limit DCD ||Image$$HEAP$$ZI$$Limit||<br />

IMPORT<br />

IMPORT<br />

||Image$$STACKS$$ZI$$Base||<br />

||Image$$STACKS$$ZI$$Limit||<br />

stack_base DCD ||Image$$STACKS$$ZI$$Limit||<br />

stack_limit DCD ||Image$$STACKS$$ZI$$Base||<br />

2-38 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


嵌 入 式 软 件 开 发<br />

2.6.3 编 译 代 码 5 示 例 代 码<br />

编 译 代 码 5 示 例 与 编 译 代 码 4 等 价 , 但 是 , 所 有 的 目 标 存 储 器 映 射 信 息 在 分 散 加<br />

载 描 述 文 件 中 定 位 , 如 第 2-34 页 的 显 式 放 置 符 号 所 示 。<br />

分 散 加 载 描 述 文 件 符 号<br />

定 位 栈 、 堆 和 外 设 的 符 号 在 汇 编 模 块 中 声 明<br />

更 新 了 分 散 加 载 描 述 文 件<br />

对 编 译 代 码 4 的 嵌 入 式 描 述 文 件 进 行 了 更 新 , 以 定 位 栈 、 堆 、 数 据<br />

TCM 和 外 设 。<br />

请 参 阅 Examples_directory\emb_sw_dev\build5 中 的 编 译 代 码 示 例 文 件 。<br />

使 用 链 接 程 序 符 号 定 位 堆 和 栈 , 请 参 阅 第 2-35 页 的 使 用 链 接 程 序 生 成 符 号 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 2-39


嵌 入 式 软 件 开 发<br />

2-40 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


第 3 章<br />

使 用 过 程 调 用 标 准<br />

本 章 描 述 如 何 使 用 <strong>ARM</strong>-Thumb 过 程 调 用 标 准 (ATPCS)。 遵 循 ATPCS 可 以 确 保<br />

分 别 编 译 和 汇 编 的 模 块 可 以 协 同 工 作 。 本 章 包 含 以 下 几 个 部 分 :<br />

• 第 3-2 页 的 关 于 <strong>ARM</strong>-Thumb 过 程 调 用 标 准 ;<br />

• 第 3-4 页 的 寄 存 器 角 色 和 名 称 ;<br />

• 第 3-6 页 的 栈 ;<br />

• 第 3-9 页 的 参 数 传 递 ;<br />

• 第 3-14 页 的 只 读 位 置 无 关 ;<br />

• 第 3-15 页 的 读 写 位 置 无 关 ;<br />

• 第 3-17 页 的 浮 点 选 项 ;<br />

• 第 3-17 页 的 浮 点 选 项 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 3-1


使 用 过 程 调 用 标 准<br />

3.1 关 于 <strong>ARM</strong>-Thumb 过 程 调 用 标 准<br />

遵 循 <strong>ARM</strong>-Thumb 过 程 调 用 标 准 (ATPCS) 可 以 确 保 分 别 编 译 或 汇 编 的 子 程 序 能 够<br />

协 同 工 作 。 本 章 描 述 如 何 使 用 ATPCS。<br />

ATPCS 有 多 个 变 体 。 本 章 提 供 的 信 息 使 您 能 够 选 择 要 使 用 的 变 体 。<br />

不 论 使 用 什 么 变 体 , 此 标 准 的 许 多 细 节 都 是 相 同 的 。 请 参 阅 :<br />

• 第 3-4 页 的 寄 存 器 角 色 和 名 称 ;<br />

• 第 3-6 页 的 栈 ;<br />

• 第 3-9 页 的 参 数 传 递 。<br />

3.1.1 ATPCS 变 体<br />

变 体 包 含 基 本 标 准 , 可 以 独 立 选 择 一 些 选 项 来 修 改 它 。 符 合 基 本 标 准 的 代 码 比 符<br />

合 其 它 变 体 的 代 码 运 行 速 度 快 , 并 且 占 用 内 存 少 。 然 而 , 符 合 基 本 标 准 的 代 码 不<br />

提 供 :<br />

• <strong>ARM</strong> 状 态 和 Thumb 状 态 之 间 的 交 互 操 作 ;<br />

• 数 据 或 代 码 位 置 独 立 ;<br />

• 使 用 独 立 数 据 的 可 重 入 调 用 ;<br />

• 栈 检 查 。<br />

编 译 程 序 或 汇 编 程 序 设 置 ELF 目 标 文 件 中 的 属 性 , 记 录 您 选 择 的 变 体 。 一 般 来<br />

说 , 您 必 须 选 择 一 个 变 体 , 然 后 将 它 用 于 必 须 协 同 工 作 的 所 有 子 程 序 。 此 规 则 的<br />

异 常 在 正 文 中 描 述 。<br />

选 项 在 以 下 标 题 中 描 述 :<br />

• 第 3-11 页 的 栈 限 制 检 查 ;<br />

• 第 3-14 页 的 只 读 位 置 无 关 ;<br />

• 第 3-15 页 的 读 写 位 置 无 关 ;<br />

• 第 3-16 页 的 <strong>ARM</strong> 状 态 和 Thumb 状 态 之 间 的 交 互 操 作 ;<br />

• 第 3-17 页 的 浮 点 选 项 。<br />

3.1.2 <strong>ARM</strong> C 库<br />

有 多 个 <strong>ARM</strong> C 库 变 体 ( 请 参 阅 <strong>RealView</strong> <strong>Compilation</strong> <strong>Tools</strong> v2.0 编 译 程 序 和 库 指<br />

南 )。 链 接 程 序 选 择 连 接 目 标 文 件 所 用 的 变 体 。 它 选 择 符 合 目 标 文 件 中 记 录 的<br />

ATPCS 选 项 的 最 佳 变 体 。 请 参 阅 <strong>RealView</strong> <strong>Compilation</strong> <strong>Tools</strong> v2.0 链 接 程 序 和 实<br />

用 程 序 指 南 中 的 链 接 程 序 一 章 。<br />

3-2 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


使 用 过 程 调 用 标 准<br />

3.1.3 符 合 ATPCS<br />

使 用 <strong>ARM</strong> 编 译 程 序 编 译 的 extern 函 数 符 合 选 定 的 ATPCS 变 体 。<br />

您 负 责 确 保 用 汇 编 语 言 编 写 的 函 数 符 合 选 定 的 ATPCS 变 体 。<br />

要 符 合 ATPCS, 汇 编 语 言 函 数 必 须 :<br />

• 在 公 开 可 见 的 接 口 中 遵 循 所 有 标 准 细 节 ;<br />

• 在 任 何 时 候 都 遵 循 ATPCS 的 栈 使 用 规 则 ;<br />

• 选 择 适 当 的 --apcs 选 项 进 行 汇 编 。<br />

3.1.4 进 程 和 内 存 模 型<br />

ATPCS 应 用 单 执 行 线 程 或 进 程 。 进 程 的 内 存 状 态 由 处 理 器 寄 存 器 内 容 和 它 可 以<br />

寻 址 的 内 存 内 容 定 义 。<br />

进 程 可 以 寻 址 以 下 一 些 或 全 部 内 存 类 型 :<br />

• 只 读 存 储 器 。<br />

• 静 态 分 配 读 写 存 储 器 。<br />

• 动 态 分 配 读 写 存 储 器 。 这 称 为 堆 内 存 。<br />

• 栈 内 存 。 请 参 阅 第 3-6 页 的 栈 。<br />

一 个 进 程 不 得 改 变 另 一 个 进 程 的 内 存 状 态 , 除 非 特 别 指 定 两 个 进 程 协 同 工 作 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 3-3


使 用 过 程 调 用 标 准<br />

3.2 寄 存 器 角 色 和 名 称<br />

ATPCS 指 定 用 于 特 定 用 途 的 寄 存 器 。<br />

3.2.1 寄 存 器 角 色<br />

除 非 另 外 声 明 , 以 下 寄 存 器 用 法 适 用 于 所 有 ATPCS 变 体 。 要 符 合 ATPCS, 必 须<br />

遵 循 这 些 规 则 :<br />

• 使 用 寄 存 器 r0-r3 将 参 数 值 传 送 到 函 数 , 并 将 结 果 值 传 出 。 可 以 用 a1-a4 来<br />

引 用 r0-r3, 以 使 此 用 法 透 明 。 请 参 阅 第 3-9 页 的 参 数 传 递 。 在 子 程 序 调 用<br />

之 间 , 可 以 将 r0-r3 用 于 任 何 用 途 。 被 调 用 函 数 在 返 回 之 前 不 必 恢 复 r0-r3。<br />

如 果 调 用 函 数 需 要 再 次 使 用 r0-r3 的 内 容 , 则 它 必 须 保 留 这 些 内 容 。<br />

• 使 用 寄 存 器 r4-r11 存 放 函 数 的 局 部 变 量 。 可 以 用 v1-v8 来 引 用 这 些 寄 存 器 ,<br />

以 使 此 用 法 透 明 。 在 Thumb 状 态 下 , 在 大 多 数 指 令 中 只 有 寄 存 器 r4-r7 可<br />

以 用 于 局 部 变 量 。<br />

如 果 被 调 用 函 数 使 用 了 这 些 寄 存 器 , 它 在 返 回 之 前 必 须 恢 复 这 些 寄 存 器<br />

的 值 。<br />

• 寄 存 器 r12 是 内 部 调 用 暂 时 寄 存 器 ip。 它 在 过 程 链 接 胶 合 代 码 ( 例 如 , 交<br />

互 操 作 胶 合 代 码 ) 中 用 于 此 角 色 。 在 过 程 调 用 之 间 , 可 以 将 它 用 于 任 何 用<br />

途 。 被 调 用 函 数 在 返 回 之 前 不 必 恢 复 r12。<br />

• 寄 存 器 r13 是 栈 指 针 sp。 它 不 能 用 于 任 何 其 它 用 途 。 sp 中 存 放 的 值 在 退 出<br />

被 调 用 函 数 时 必 须 与 进 入 时 的 值 相 同 。<br />

• 寄 存 器 r14 是 链 接 寄 存 器 lr。 如 果 您 保 存 了 返 回 地 址 , 则 可 以 在 调 用 之 间<br />

将 r14 用 于 其 它 用 途 。<br />

• 寄 存 器 r15 是 程 序 计 数 器 PC。 它 不 能 用 于 任 何 其 它 用 途 。<br />

3-4 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


使 用 过 程 调 用 标 准<br />

3.2.2 寄 存 器 名 称<br />

表 3-1 列 出 处 理 器 寄 存 器 的 定 义 角 色 和 相 关 名 称 。 这 些 名 称 及 其 同 义 词 预 先 定 义<br />

在 汇 编 程 序 中 。 生 成 汇 编 程 序 语 言 时 , 编 译 程 序 使 用 特 定 名 称 和 基 本 寄 存 器 名 。<br />

寄 存 器 同 义 词 特 定 名 称 过 程 调 用 标 准 中 的 角 色<br />

r15 - PC 程 序 计 数 器 。<br />

r14 - lr 链 接 寄 存 器 。<br />

r13 - sp 栈 指 针 。<br />

r12 - ip 内 部 过 程 调 用 暂 时 寄 存 器 。<br />

r11 v8 - <strong>ARM</strong> 状 态 变 量 寄 存 器 8。<br />

表 3-1 ATPCS 中 的 寄 存 器 角 色 和 名 称<br />

r10 v7 sl <strong>ARM</strong> 状 态 变 量 寄 存 器 7。 栈 检 查 变 体 中 的 栈<br />

限 制 指 针 。<br />

r9 v6 sb <strong>ARM</strong> 状 态 变 量 寄 存 器 6。RWPI 变 体 中 的 静 态<br />

基 址 。<br />

r8 v5 - <strong>ARM</strong> 状 态 变 量 寄 存 器 5。<br />

r7 v4 - 变 量 寄 存 器 4。<br />

r6 v3 - 变 量 寄 存 器 3。<br />

r5 v2 - 变 量 寄 存 器 2。<br />

r4 v1 - 变 量 寄 存 器 1。<br />

r3 a4 - 自 变 量 / 结 果 / 暂 时 寄 存 器 4。<br />

r2 a3 - 自 变 量 / 结 果 / 暂 时 寄 存 器 3。<br />

r1 a2 - 自 变 量 / 结 果 / 暂 时 寄 存 器 2。<br />

r0 a1 - 自 变 量 / 结 果 / 暂 时 寄 存 器 1。<br />

另 外 ,s0-s31、d0-d15 和 f0-f31 是 浮 点 协 处 理 器 中 寄 存 器 的 预 定 义 名 称 。 有 关 详<br />

细 信 息 请 参 阅 第 3-18 页 的 VFP 体 系 结 构 和 第 3-20 页 的 FPA 体 系 结 构 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 3-5


使 用 过 程 调 用 标 准<br />

3.3 栈<br />

此 部 分 描 述 在 基 本 标 准 中 如 何 使 用 栈 。 另 请 参 阅 第 3-11 页 的 栈 限 制 检 查 。<br />

ATPCS 指 定 :<br />

• 完 整 的 降 序 栈 ;<br />

• 所 有 外 部 接 口 的 8 字 节 栈 对 齐 。<br />

3.3.1 栈 术 语<br />

ATPCS 中 使 用 以 下 栈 相 关 术 语 :<br />

栈 指 针 写 入 ( 推 入 ) 栈 的 最 后 一 个 值 的 地 址 。<br />

栈 基 址<br />

栈 顶 的 地 址 , 栈 从 此 处 向 下 增 长 。 栈 实 际 使 用 的 最 高 位 置 是 栈 基 址<br />

下 面 的 第 一 个 字 。<br />

栈 限 制 允 许 当 前 进 程 使 用 的 栈 的 最 低 地 址 。<br />

已 使 用 栈 栈 基 址 和 栈 指 针 之 间 的 内 存 区 。 它 包 括 栈 指 针 , 但 不 包 括 栈 基 址 。<br />

未 使 用 栈 栈 指 针 和 栈 限 制 之 间 的 内 存 区 。 它 包 括 栈 限 制 , 但 不 包 括 栈 指 针 。<br />

栈 框 架 函 数 分 配 的 栈 内 存 区 , 用 于 保 存 寄 存 器 和 存 放 局 部 变 量 。<br />

进 程 可 能 有 ( 或 可 能 没 有 ) 访 问 栈 基 址 和 栈 限 制 当 前 值 的 权 限 。<br />

中 断 处 理 程 序 可 以 使 用 被 它 中 断 的 进 程 的 栈 。 在 此 情 况 下 , 程 序 员 负 责 确 保 不 超<br />

出 栈 限 制 。<br />

第 3-7 页 的 图 3-1 显 示 栈 内 存 布 局 。<br />

3-6 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


使 用 过 程 调 用 标 准<br />

图 3-1 栈 内 存 布 局<br />

3.3.2 栈 展 开<br />

编 译 的 目 标 文 件 总 是 包 含 DWARF2 调 试 框 架 信 息 。 在 调 试 期 间 , 调 试 程 序 使 用<br />

此 信 息 在 必 要 时 展 开 栈 。 这 使 您 可 以 在 调 试 程 序 中 回 溯 栈<br />

在 汇 编 语 言 中 , 您 负 责 使 用 FRAME 指 令 描 述 栈 框 架 。 当 使 用 -g 汇 编 时 , 汇 编 程 序<br />

使 用 这 些 描 述 生 成 DWARF2 调 试 框 架 信 息 。 请 参 阅 编 写 <strong>ARM</strong> 和 Thumb 汇 编 语<br />

言 和 <strong>RealView</strong> 编 译 工 具 2.0 版 汇 编 程 序 指 南 中 的 指 令 参 考 一 章 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 3-7


使 用 过 程 调 用 标 准<br />

3.3.3 8 字 节 对 齐<br />

对 于 一 些 系 统 中 的 多 个 传 输 , 8 字 节 对 齐 地 址 可 以 改 进 内 存 访 问 速 度 。 对 于<br />

<strong>ARM</strong>v5TE 和 其 后 的 新 处 理 器 中 的 LDRD 和 STRD 指 令 , 需 要 8 字 节 对 齐 。<br />

编 译 程 序 生 成 的 目 标 文 件 在 所 有 外 部 接 口 保 留 8 字 节 对 齐 栈 。 编 译 程 序 设 置 编<br />

译 属 性 , 向 链 接 程 序 指 示 此 特 征 。<br />

要 在 汇 编 语 言 中 符 合 ATPCS, 除 非 目 标 文 件 不 包 含 外 部 调 用 , 否 则 必 须 :<br />

• 确 保 在 所 有 外 部 接 口 保 留 了 8 字 节 对 齐 栈 。( 在 代 码 入 口 和 代 码 中 的 任 何<br />

外 部 调 用 之 间 , 栈 指 针 必 须 总 是 移 动 偶 数 个 字 。)<br />

• 使 用 PRESERVE8 指 令 通 知 链 接 程 序 , 已 保 留 了 8 字 节 对 齐 ( 请 参 阅 <strong>RealView</strong><br />

编 译 工 具 2.0 版 汇 编 程 序 指 南 中 的 指 令 参 考 一 章 )。<br />

3-8 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


使 用 过 程 调 用 标 准<br />

3.4 参 数 传 递<br />

有 可 变 个 数 自 变 量 的 函 数 是 variadic。 有 固 定 个 数 自 变 量 的 函 数 是 nonvariadic。<br />

向 variadic 和 nonvariadic 函 数 传 递 参 数 有 不 同 的 规 则 。<br />

此 部 分 描 述 基 本 标 准 。 有 关 浮 点 选 项 的 更 多 信 息 , 请 参 阅 第 3-17 页 的 浮 点 选 项 。<br />

3.4.1 Nonvariadic 函 数<br />

参 数 值 以 下 列 方 式 传 递 到 nonvariadic 函 数 :<br />

1. 前 面 的 整 型 自 变 量 按 顺 序 分 配 给 r0-r3 ( 请 参 阅 长 整 数 分 配 )。<br />

2. 其 余 参 数 按 顺 序 分 配 给 栈 ( 请 参 阅 长 整 数 分 配 )。<br />

警 告<br />

栈 访 问 时 将 显 著 增 加 代 码 大 小 并 降 低 执 行 速 度 。 尽 可 能 将 参 数 个 数 限 制 为<br />

少 于 5 个 。<br />

长 整 数 分 配<br />

超 过 32 位 的 整 型 参 数 ( 例 如 , long long 型 ) 有 8 字 节 对 齐 。 传 递 long long 型<br />

参 数 时 , 将 它 分 配 给 寄 存 器 r2 和 r3, 或 者 分 配 给 栈 。<br />

浮 点 数 分 配<br />

如 果 系 统 有 浮 点 硬 件 , 则 FP 参 数 如 下 列 方 式 分 配 给 FP 寄 存 器 :<br />

1. 按 次 序 检 查 每 个 FP 参 数 。<br />

2. 对 于 每 个 参 数 , 检 查 可 用 的 FP 寄 存 器 组 。<br />

3. 如 果 有 一 个 可 用 , 则 将 编 号 最 低 、 尺 寸 适 合 于 参 数 的 相 邻 FP 寄 存 器 组 分 配<br />

给 参 数 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 3-9


使 用 过 程 调 用 标 准<br />

3.4.2 Variadic 函 数<br />

参 数 值 在 整 型 寄 存 器 a1-a4 中 、 必 要 时 在 栈 中 传 递 到 variadic 函 数 (a1-a4 是 r0-r3<br />

的 同 义 词 )。<br />

使 用 的 字 顺 序 如 同 参 数 值 存 储 在 连 续 内 存 字 中 , 然 后 传 输 到 :<br />

1. a1-a4, 首 先 是 a1。<br />

2. 栈 , 首 先 是 最 低 地 址 。( 这 表 示 它 们 以 相 反 的 顺 序 推 入 栈 中 。)<br />

备 注<br />

因 此 , 浮 点 值 可 能 在 整 型 寄 存 器 、 栈 中 传 递 , 或 者 分 在 整 型 寄 存 器 和 栈 中 传 递 。<br />

3.4.3 结 果 返 回<br />

函 数 可 以 :<br />

• 在 a1 中 返 回 单 字 整 型 值 。<br />

• 在 a1-a2、 a1-a3 或 a1-a4 中 返 回 双 字 或 四 字 整 型 值 。<br />

• 在 f0、 d0 或 s0 中 返 回 浮 点 值 。<br />

• 在 f0-fN 或 d0-dN 中 返 回 复 合 浮 点 值 ( 如 complex)。 N 的 最 大 值 取 决 于 所<br />

选 的 浮 点 结 构 ( 请 参 阅 第 3-17 页 的 浮 点 选 项 )。<br />

• 较 长 的 值 必 须 在 内 存 中 间 接 返 回 。<br />

3-10 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


使 用 过 程 调 用 标 准<br />

3.5 栈 限 制 检 查<br />

除 非 可 以 在 设 计 阶 段 精 确 地 计 算 出 整 个 程 序 所 需 的 最 大 栈 内 存 量 , 否 则 请 选 择<br />

软 件 栈 限 制 检 查 选 项 (-apcs /swst)。<br />

仅 当 可 以 在 设 计 阶 段 精 确 地 计 算 出 整 个 程 序 所 需 的 最 大 栈 内 存 量 时 , 才 选 择 不<br />

要 软 件 栈 限 制 检 查 选 项 (-apcs /swst)。 这 是 默 认 选 项 。<br />

可 以 编 写 汇 编 代 码 , 使 栈 限 制 检 查 不 相 关 。 文 件 中 的 代 码 可 能 不 需 要 栈 限 制 检<br />

查 , 但 仍 然 与 其 它 用 -apcs /swst 或 默 认 的 -apcs /noswst 汇 编 的 代 码 兼 容 。 在 此<br />

情 况 下 , 请 使 用 软 件 栈 限 制 检 查 不 适 用 选 项 (-apcs /swstna)。<br />

3.5.1 栈 限 制 检 查 代 码 规 则<br />

在 ATPCS 的 栈 限 制 检 查 变 体 中 :<br />

• 栈 限 制 指 针 (sl) 必 须 指 向 栈 中 最 低 可 用 地 址 之 上 至 少 256 字 节 处 。<br />

备 注<br />

如 果 中 断 处 理 程 序 可 以 使 用 “ 用 户 ” 模 式 栈 , 则 必 须 在 s1 和 栈 中 最 低 可<br />

用 地 址 之 间 , 在 256 字 节 之 外 为 它 分 配 足 够 的 空 间 。<br />

• 不 能 用 选 择 了 栈 限 制 检 查 进 行 编 译 或 汇 编 的 代 码 改 变 s1。s1 由 运 行 时 支 持<br />

的 代 码 改 变 。<br />

• 存 放 在 栈 指 针 (sp) 中 的 值 必 须 总 是 大 于 或 等 于 sl 中 的 值 。<br />

3.5.2 栈 限 制 检 查 的 寄 存 器 用 法<br />

不 得 在 选 择 了 栈 检 查 选 项 进 行 汇 编 或 编 译 的 函 数 中 改 变 r10 或 恢 复 它 。 寄 存 器<br />

r10 是 栈 限 制 指 针 sl。<br />

在 所 有 其 它 方 面 , 寄 存 器 的 用 法 相 同 , 不 论 使 用 或 不 使 用 栈 限 制 检 查 ( 请 参 阅<br />

第 3-4 页 的 寄 存 器 角 色 和 名 称 )。<br />

3.5.3 C 和 C++ 中 的 栈 检 查<br />

如 果 选 择 软 件 栈 限 制 检 查 (-apcs /swst) 选 项 , 则 编 译 程 序 生 成 执 行 栈 检 查 的 对<br />

象 代 码 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 3-11


使 用 过 程 调 用 标 准<br />

3.5.4 汇 编 语 言 中 的 栈 检 查<br />

如 果 您 对 汇 编 代 码 选 择 了 软 件 栈 检 查 (/swst) 选 项 , 则 您 负 责 编 写 执 行 栈 检 查 的<br />

代 码 。<br />

叶 函 数 是 不 调 用 任 何 其 它 子 程 序 的 函 数 。<br />

必 须 考 虑 以 下 情 况 :<br />

• 使 用 少 于 256 字 节 栈 的 叶 函 数 ;<br />

• 使 用 少 于 256 字 节 栈 的 非 叶 函 数 ;<br />

• 第 3-13 页 的 使 用 超 过 256 字 节 栈 的 函 数 。<br />

因 此 , 叶 函 数 包 含 的 函 数 中 每 个 调 用 都 是 尾 调 用 。<br />

使 用 少 于 256 字 节 栈 的 叶 函 数<br />

使 用 少 于 256 字 节 栈 的 叶 函 数 不 需 要 检 查 栈 限 制 。 这 是 上 述 规 则 的 结 果 ( 请 参<br />

阅 第 3-11 页 的 栈 限 制 检 查 代 码 规 则 )。<br />

因 此 , 叶 函 数 可 以 是 总 计 栈 使 用 量 少 于 256 字 节 的 多 个 函 数 的 组 合 。<br />

使 用 少 于 256 字 节 栈 的 非 叶 函 数<br />

调 用 都 是 尾 调 用<br />

使 用 少 于 256 字 节 栈 的 非 叶 函 数 可 以 使 用 如 下 的 限 界 检 查 序 列 :<br />

SUB sp, sp, #size ; <strong>ARM</strong> code version<br />

CMP sp, sl<br />

BLLO __<strong>ARM</strong>_stack_overflow<br />

或 用 Thumb 代 码 :<br />

ADD sp, #-size ; Thumb code version<br />

CMP sp, sl<br />

BLLO __Thumb_stack_overflow<br />

备 注<br />

名 称 __<strong>ARM</strong>_stack_overflow 和 __Thumb_stack_overflow 是 说 明 性 的 , 不 对 应 于 任 何<br />

实 际 的 实 现 。<br />

3-12 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


使 用 过 程 调 用 标 准<br />

使 用 超 过 256 字 节 栈 的 函 数<br />

在 此 情 况 下 , 必 须 使 用 如 下 的 序 列 向 限 界 检 查 代 码 提 供 一 个 新 sp 值 。<br />

SUB ip, sp, #size ; <strong>ARM</strong> code version<br />

CMP ip, sl<br />

BLLO __<strong>ARM</strong>_stack_overflow<br />

或 用 Thumb 代 码 :<br />

LDR r7, #-size ; Thumb code version<br />

ADD r7, sp<br />

CMP r7, sl<br />

BLLO __Thumb_stack_overflow<br />

这 是 必 需 的 , 以 确 保 sp 不 小 于 栈 中 的 最 低 可 用 地 址 。<br />

备 注<br />

名 称 __<strong>ARM</strong>_stack_overflow 和 __Thumb_stack_overflow 是 说 明 性 的 , 不 对 应 于 任 何<br />

实 际 的 实 现 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 3-13


使 用 过 程 调 用 标 准<br />

3.6 只 读 位 置 无 关<br />

如 果 程 序 的 所 有 只 读 段 都 是 位 置 无 关 的 , 则 该 程 序 是 只 读 位 置 无 关 的 (ROPI)。<br />

ROPI 段 通 常 是 位 置 无 关 代 码 (PIC), 但 也 可 能 是 只 读 数 据 或 PIC 和 只 读 数 据 的<br />

组 合 。<br />

选 择 ROPI 选 项 可 以 避 免 必 须 将 代 码 载 入 特 定 的 内 存 位 置 。 这 对 以 下 函 数 尤 其<br />

有 用 :<br />

• 根 据 运 行 时 事 件 载 入 的 函 数 ;<br />

• 与 不 同 环 境 中 的 其 它 函 数 的 不 同 组 合 一 起 载 入 内 存 的 函 数 ;<br />

• 在 执 行 期 间 映 射 到 不 同 地 址 的 函 数 。<br />

3.6.1 ROPI 的 寄 存 器 用 法<br />

不 论 使 用 或 未 使 用 ROPI, 寄 存 器 的 用 法 相 同 ( 请 参 阅 第 3-4 页 的 寄 存 器 角 色 和<br />

名 称 )。<br />

3.6.2 编 写 ROPI 代 码<br />

当 编 写 ROPI 代 码 时 :<br />

• ROPI 段 中 的 代 码 对 同 一 个 ROPI 段 的 符 号 的 每 个 引 用 必 须 是 相 对 于 PC<br />

的 。 ATPCS 不 为 只 读 段 定 义 任 何 其 它 基 本 寄 存 器 。 一 个 ROPI 段 中 的 项 的<br />

地 址 不 能 分 配 给 不 同 ROPI 段 中 的 项 。<br />

• ROPI 段 中 的 代 码 对 不 同 ROPI 段 的 符 号 的 每 个 引 用 必 须 是 相 对 于 PC 的 。<br />

两 个 段 必 须 是 互 相 固 定 相 对 的 。<br />

• 来 自 ROPI 段 的 其 它 引 用 必 须 指 向 :<br />

— 绝 对 地 址 ;<br />

— 对 可 写 数 据 的 sb 相 对 引 用 ( 请 参 阅 第 3-15 页 的 读 写 位 置 无 关 )。<br />

• 引 用 ROPI 段 的 符 号 的 可 读 写 字 在 ROPI 段 移 动 时 必 须 进 行 调 整 。<br />

3-14 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


使 用 过 程 调 用 标 准<br />

3.7 读 写 位 置 无 关<br />

如 果 程 序 的 所 有 读 写 段 都 是 位 置 无 关 的 , 则 该 程 序 是 读 写 位 置 无 关 的 (RWPI)。<br />

RWPI 段 通 常 是 位 置 无 关 数 据 (PID)。<br />

选 择 RWPI 选 项 可 以 避 免 将 数 据 固 定 在 内 存 中 特 定 的 位 置 。 这 对 于 必 须 为 可 重 入<br />

函 数 而 多 次 实 例 化 的 数 据 尤 其 有 用 。<br />

3.7.1 可 重 入 函 数<br />

可 重 入 函 数 可 以 同 时 成 为 多 个 进 程 的 线 程 。 每 个 进 程 有 其 各 自 的 该 函 数 读 写 段<br />

副 本 。 每 个 副 本 用 不 同 的 静 态 基 本 寄 存 器 编 址 。<br />

3.7.2 RWPI 的 寄 存 器 用 法<br />

寄 存 器 r9 是 静 态 基 址 sb。 当 调 用 任 何 外 部 可 见 函 数 时 , 它 必 须 指 向 适 当 的 静 态<br />

数 据 段 基 址 。<br />

在 不 使 用 sb 的 函 数 中 , 可 以 将 r9 用 于 其 它 用 途 。 如 果 这 样 做 , 您 必 须 在 进 入 函<br />

数 时 保 存 sb 的 内 容 , 并 且 在 退 出 之 前 恢 复 它 。 在 调 用 任 何 外 部 函 数 之 前 , 也 必<br />

须 恢 复 它 。<br />

在 所 有 其 它 方 面 , 不 论 使 用 或 未 使 用 RWPI, 寄 存 器 的 用 法 相 同 ( 请 参 阅 第 3-4<br />

页 的 寄 存 器 角 色 和 名 称 )。<br />

3.7.3 位 置 无 关 数 据 编 址<br />

RWPI 段 可 以 在 首 次 使 用 之 前 重 新 定 位 。 RWPI 段 中 符 号 的 地 址 如 下 计 算 :<br />

1. 链 接 程 序 从 段 中 一 个 固 定 位 置 计 算 只 读 偏 移 。 按 照 惯 例 , 该 固 定 位 置 是 程<br />

序 的 最 低 地 址 RWPI 段 的 第 一 个 字 节 。<br />

2. 运 行 时 , 它 作 为 偏 移 添 加 到 静 态 基 本 寄 存 器 sb 的 内 容 上 。<br />

3.7.4 编 写 汇 编 语 言 RWPI<br />

通 过 sb 值 加 上 一 个 固 定 ( 只 读 ) 偏 移 , 构 建 从 只 读 段 到 RWPI 段 的 引 用 ( 请 参<br />

阅 <strong>RealView</strong> 编 译 工 具 2.0 版 汇 编 程 序 指 南 中 指 令 参 考 一 章 里 的 DCDO)。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 3-15


使 用 过 程 调 用 标 准<br />

3.8 <strong>ARM</strong> 状 态 和 Thumb 状 态 之 间 的 交 互 操 作<br />

当 编 译 或 汇 编 代 码 时 , 可 以 选 择 /interwork 选 项 来 满 足 以 下 需 求 :<br />

• <strong>ARM</strong> 函 数 能 够 返 回 到 Thumb 状 态 调 用 者 ;<br />

• Thumb 函 数 能 够 返 回 到 <strong>ARM</strong> 状 态 调 用 者 ;<br />

• 当 从 <strong>ARM</strong> 调 用 Thumb 或 从 Thumb 调 用 <strong>ARM</strong> 时 , 链 接 程 序 提 供 用 于 改 变<br />

状 态 的 代 码 。<br />

当 编 译 或 汇 编 代 码 时 , 在 以 下 情 况 下 , 应 选 择 /nointerwork 选 项 :<br />

• 系 统 未 使 用 Thumb ;<br />

• 您 提 供 用 于 处 理 所 有 状 态 改 变 的 汇 编 程 序 代 码 。<br />

默 认 设 置 是 :<br />

• /interwork, 如 果 编 译 或 汇 编 <strong>ARM</strong> v5T 处 理 器 代 码 ;<br />

• /nointerwork, 用 于 其 它 情 况 。<br />

如 果 选 择 交 互 操 作 选 项 , 则 可 以 调 用 不 同 模 块 中 的 函 数 , 无 需 考 虑 它 所 使 用 的 指<br />

令 。 如 果 有 必 要 , 链 接 程 序 将 插 入 一 个 交 互 操 作 调 用 胶 合 代 码 , 或 者 修 补 调 用<br />

点 。 这 适 用 于 已 编 译 或 已 汇 编 的 代 码 。<br />

有 关 详 细 信 息 , 请 参 阅 第 4 章 <strong>ARM</strong> 和 Thumb 交 互 操 作 。<br />

3.8.1 交 互 操 作 的 寄 存 器 用 法<br />

不 论 使 用 或 未 使 用 交 互 操 作 , 寄 存 器 的 用 法 相 同 ( 请 参 阅 第 3-4 页 的 寄 存 器 角<br />

色 和 名 称 )。<br />

3-16 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


使 用 过 程 调 用 标 准<br />

3.9 浮 点 选 项<br />

ATPCS 支 持 以 下 浮 点 硬 件 体 系 结 构 和 指 令 集 :<br />

• VFP 体 系 结 构 ( 请 参 阅 第 3-18 页 的 VFP 体 系 结 构 )。<br />

• FPA 体 系 结 构 ( 请 参 阅 第 3-20 页 的 FPA 体 系 结 构 )。 这 只 是 为 了 向 后<br />

兼 容 。<br />

一 个 体 系 结 构 的 代 码 不 能 用 于 其 它 体 系 结 构 。<br />

<strong>ARM</strong> 编 译 程 序 和 汇 编 程 序 有 以 下 浮 点 选 项 :<br />

• -fpu vfp ;<br />

• -fpu vfpv1 ;<br />

• -fpu vfpv2 ;<br />

• -fpu fpa ;<br />

• -fpu softvfp ;<br />

• -fpu softvfp+vfp ;<br />

• -fpu softvfp+vfpv2 ;<br />

• -fpu softfpa ;<br />

• -fpu none。<br />

如 果 目 标 系 统 有 浮 点 硬 件 , 请 选 择 vfp、 softvfp+vfp 或 fpa。<br />

如 果 系 统 有 浮 点 硬 件 , 并 且 想 要 从 Thumb 代 码 使 用 浮 点 库 函 数 , 请 使 用<br />

softvfp+vfp 或 softvfp+vfpv2。<br />

如 果 目 标 系 统 没 有 浮 点 硬 件 , 则 :<br />

• 如 果 需 要 与 FPA 系 统 或 SDT 下 生 成 的 对 象 兼 容 , 请 选 择 softfpa。<br />

• 如 果 编 译 或 汇 编 的 模 块 未 使 用 浮 点 算 法 , 并 且 需 要 与 FPA 和 VFP 系 统 兼<br />

容 , 请 选 择 none。<br />

• 否 则 , 请 选 择 softvfp。 这 是 默 认 选 项 。<br />

另 请 参 阅 第 3-21 页 的 没 有 浮 点 硬 件 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 3-17


使 用 过 程 调 用 标 准<br />

3.9.1 VFP 体 系 结 构<br />

VFP 体 系 结 构 有 十 六 个 双 精 度 寄 存 器 d0-d15。 每 个 双 精 度 寄 存 器 可 以 用 作 两 个<br />

单 精 度 寄 存 器 。 作 为 单 精 度 寄 存 器 , 它 们 称 为 s0-s31。 例 如 , d5 相 当 于 s10 和<br />

s11。<br />

VFP 体 系 结 构 不 支 持 扩 展 精 度 。<br />

向 量 和 标 量 模 式<br />

VFP 体 系 结 构 有 以 下 操 作 模 式 :<br />

• 标 量 模 式 ;<br />

• 向 量 模 式 。<br />

ATPCS 仅 适 用 于 标 量 模 式 操 作 。 进 入 和 退 出 符 合 ATPCS 的 公 开 可 见 函 数 时 , 向<br />

量 长 度 和 向 量 跨 度 都 必 须 设 为 1。<br />

VFP 的 寄 存 器 用 法<br />

前 8 个 双 精 度 寄 存 器 d0-d7 可 以 用 于 :<br />

• 将 浮 点 值 传 递 到 函 数 ;<br />

• 将 浮 点 值 传 出 函 数 ;<br />

• 函 数 内 的 暂 时 寄 存 器 。<br />

每 个 双 精 度 寄 存 器 可 以 存 放 一 个 双 精 度 值 或 两 个 单 精 度 值 。 通 过 将 每 个 值 依 次<br />

分 配 给 下 一 个 适 当 类 型 的 空 闲 寄 存 器 , 将 浮 点 自 变 量 值 分 配 给 浮 点 寄 存 器 。<br />

图 3-2 显 示 参 数 值 分 配 给 寄 存 器 , 其 中 传 递 值 1.0 ( 双 精 度 )、 2.0 ( 双 精 度 )、<br />

3.0 ( 单 精 度 )、 4.0 ( 双 精 度 )、 5.0 ( 单 精 度 ) 和 6.0 ( 单 精 度 )。<br />

图 3-2 将 参 数 值 分 配 给 寄 存 器<br />

3-18 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


使 用 过 程 调 用 标 准<br />

要 符 合 ATPCS, 如 果 在 函 数 中 使 用 寄 存 器 d8-d15, 则 必 须 在 进 入 时 保 存 它 们 的<br />

值 , 并 且 在 退 出 之 前 恢 复 它 们 。 可 以 使 用 单 个 FSTMX 指 令 保 存 它 们 , 使 用 单 个<br />

FLDMX 指 令 恢 复 它 们 。 它 们 以 位 模 式 保 存 和 恢 复 , 无 需 解 释 为 单 精 度 或 双 精 度<br />

数 。 保 存 的 N 个 单 精 度 值 占 用 N+1 个 字 。<br />

VFP 值 格 式<br />

单 精 度 和 双 精 度 值 遵 循 IEEE 754 标 准 格 式 。 双 精 度 值 视 为 真 64 位 值 :<br />

• 在 小 端 模 式 中 , 包 含 指 数 的 双 字 双 精 度 值 的 更 有 效 字 有 较 高 地 址 ;<br />

• 在 大 端 模 式 中 , 更 有 效 的 字 有 较 低 地 址 。<br />

备 注<br />

VFP 中 的 小 端 双 精 度 值 是 纯 小 端 的 。 这 与 FPA 体 系 结 构 不 同 。<br />

VFP 和 FPA 体 系 结 构 中 的 大 端 双 精 度 值 是 相 同 的 , 都 是 纯 大 端 的 。<br />

IEEE 舍 入 模 式 和 异 常 启 用 标 志<br />

在 进 入 或 退 出 符 合 标 准 的 函 数 时 , ATPCS 不 对 这 些 状 态 指 定 任 何 约 束 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 3-19


使 用 过 程 调 用 标 准<br />

3.9.2 FPA 体 系 结 构<br />

FPA 体 系 结 构 有 8 个 浮 点 寄 存 器 f0-f7。 每 个 寄 存 器 可 以 存 放 单 精 度 、 双 精 度 或<br />

扩 展 精 度 值 。<br />

FPA 的 寄 存 器 用 法<br />

前 四 个 浮 点 寄 存 器 f0-f3 可 以 用 于 :<br />

• 将 浮 点 值 传 递 到 函 数 ;<br />

• 将 浮 点 结 果 传 出 函 数 ;<br />

• 函 数 内 的 暂 存 寄 存 器 。<br />

要 符 合 ATPCS, 如 果 在 函 数 中 使 用 浮 点 寄 存 器 f4-f7, 则 必 须 在 进 入 时 保 存 它 们<br />

的 值 , 并 且 在 退 出 之 前 恢 复 它 们 。 可 以 使 用 单 个 SFM 指 令 保 存 它 们 , 使 用 单 个 LFM<br />

指 令 恢 复 它 们 。 每 个 保 存 的 值 占 用 三 个 字 。<br />

FPA 值 格 式<br />

单 精 度 和 双 精 度 值 遵 循 IEEE 754 标 准 格 式 。 包 含 指 数 的 浮 点 值 的 最 高 有 效 字 有<br />

最 低 内 存 地 址 。 无 论 字 中 的 字 节 顺 序 是 大 端 或 小 端 , 都 是 一 样 的 。<br />

备 注<br />

小 端 双 精 度 值 既 不 是 纯 小 端 的 , 也 不 是 纯 大 端 的 。<br />

IEEE 舍 入 模 式 和 异 常 启 用 标 志<br />

在 进 入 或 退 出 符 合 标 准 的 函 数 时 , ATPCS 不 对 这 些 状 态 指 定 任 何 约 束 。<br />

3-20 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


使 用 过 程 调 用 标 准<br />

3.9.3 没 有 浮 点 硬 件<br />

softvfp 和 softfpa 之 间 的 唯 一 不 同 点 是 小 端 模 式 中 双 精 度 值 的 字 顺 序 ( 请 参 阅<br />

第 3-18 页 的 VFP 体 系 结 构 和 第 3-20 页 的 FPA 体 系 结 构 )。<br />

如 果 指 定 -fpu none, 则 不 能 使 用 浮 点 值 。<br />

softvfp 和 softfpa 的 寄 存 器 用 法<br />

每 个 浮 点 自 变 量 转 换 为 一 个 或 两 个 整 型 字 的 位 模 式 , 如 同 保 存 在 内 存 中 一 样 。<br />

如 第 3-9 页 的 参 数 传 递 中 所 述 传 递 结 果 整 型 值 。<br />

单 精 度 浮 点 结 果 以 位 模 式 在 r0 中 返 回 。<br />

双 精 度 浮 点 结 果 在 r0 和 r1 中 返 回 。 r0 包 含 的 字 对 应 于 内 存 中 表 示 的 值 的 低 地<br />

址 字 。<br />

3.9.4 softvfp+vfp 和 softvfp+vfpv2<br />

Thumb 代 码 不 能 在 浮 点 寄 存 器 中 传 递 浮 点 值 , 因 为 Thumb 没 有 协 处 理 器 指 令 。<br />

如 果 有 VFP 协 处 理 器 , 并 且 想 要 从 Thumb 代 码 使 用 浮 点 函 数 , 请 选 择 -fpu<br />

softvfp+vfp 或 -fpu softvfp+vfpv2 选 项 。<br />

这 指 示 编 译 程 序 使 用 与 -fpu softvfp 相 同 的 参 数 传 递 规 则 生 成 代 码 。C 库 浮 点 函<br />

数 使 用 <strong>ARM</strong> 状 态 的 VFP 指 令 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 3-21


使 用 过 程 调 用 标 准<br />

3-22 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


第 4 章<br />

<strong>ARM</strong> 和 Thumb 交 互 操 作<br />

本 章 介 绍 为 实 现 Thumb 指 令 集 的 处 理 器 编 写 代 码 时 如 何 在 <strong>ARM</strong> 状 态 和 Thumb<br />

状 态 之 间 变 化 。 它 包 含 以 下 几 个 部 分 :<br />

• 第 4-2 页 的 关 于 交 互 操 作 ;<br />

• 第 4-5 页 的 汇 编 语 言 交 互 操 作 ;<br />

• 第 4-10 页 的 C 和 C++ 交 互 操 作 和 胶 合 代 码 ;<br />

• 第 4-14 页 的 使 用 胶 合 代 码 的 汇 编 语 言 交 互 操 作 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 4-1


<strong>ARM</strong> 和 Thumb 交 互 操 作<br />

4.1 关 于 交 互 操 作<br />

根 据 需 要 可 将 <strong>ARM</strong> 和 Thumb 代 码 混 合 , 其 条 件 是 代 码 符 合 <strong>ARM</strong>-Thumb 过 程 调<br />

用 标 准 (ATPCS) 的 要 求 。<strong>ARM</strong> 编 译 程 序 总 是 生 成 符 合 此 标 准 的 代 码 。 编 写 <strong>ARM</strong><br />

汇 编 语 言 模 块 时 , 必 须 确 保 代 码 的 一 致 性 。<br />

<strong>ARM</strong> 链 接 程 序 检 测 何 时 从 Thumb 状 态 下 调 用 <strong>ARM</strong> 函 数 , 或 者 何 时 从 <strong>ARM</strong> 状<br />

态 调 用 Thumb 函 数 。<strong>ARM</strong> 链 接 程 序 通 过 改 变 调 用 和 返 回 指 令 或 插 入 名 为 胶 合 代<br />

码 的 小 代 码 段 , 按 照 需 要 更 改 处 理 器 的 状 态 。<br />

<strong>ARM</strong> 体 系 结 构 5T 版 提 供 更 改 处 理 器 状 态 而 不 使 用 任 何 额 外 指 令 的 方 法 。 通 常<br />

在 <strong>ARM</strong> 体 系 结 构 5T 版 处 理 器 上 交 互 操 作 无 需 任 何 成 本 。<br />

如 果 将 几 个 源 文 件 链 接 在 一 起 , 所 有 的 文 件 必 须 使 用 兼 容 的 ATPCS 选 项 如 果 检<br />

测 到 不 兼 容 的 选 项 , 链 接 程 序 会 产 生 一 条 错 误 信 息 。<br />

4.1.1 何 时 使 用 交 互 操 作<br />

在 为 能 够 支 持 Thumb 的 <strong>ARM</strong> 处 理 器 编 写 代 码 时 , 可 能 多 数 的 程 序 需 要 在<br />

Thumb 状 态 下 运 行 。 这 会 使 代 码 密 度 最 佳 。 使 用 8 位 或 16 位 宽 存 储 器 , 它 也 使<br />

其 性 能 最 佳 。 但 是 , 可 能 需 要 部 分 在 <strong>ARM</strong> 状 态 下 运 行 的 应 用 程 序 , 其 原 因 如 下 :<br />

速 度<br />

功 能<br />

在 应 用 程 序 的 某 些 部 分 , 速 度 可 能 是 关 键 的 。 这 些 段 在 <strong>ARM</strong> 状 态<br />

下 运 行 时 的 效 率 可 能 比 在 Thumb 状 态 下 运 行 时 更 高 。 在 某 些 情 况<br />

下 , 单 条 <strong>ARM</strong> 指 令 可 以 比 等 价 的 Thumb 指 令 执 行 更 多 操 作<br />

有 些 系 统 包 括 少 量 的 快 速 32 位 存 储 器 。 <strong>ARM</strong> 代 码 可 在 其 中 运 行 ,<br />

而 无 需 从 8 位 或 16 位 存 储 器 存 取 每 一 条 指 令 的 开 销 。<br />

Thumb 指 令 不 如 其 等 价 的 <strong>ARM</strong> 指 令 灵 活 。 在 Thumb 状 态 下 有 些 操<br />

作 是 不 可 能 执 行 的 。 例 如 , 不 能 启 用 或 禁 用 中 断 、 或 者 访 问 协 处 理<br />

器 。 需 要 更 改 状 态 , 才 能 执 行 这 些 操 作 。<br />

4-2 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


<strong>ARM</strong> 和 Thumb 交 互 操 作<br />

异 常 处 理<br />

发 生 处 理 器 异 常 时 处 理 器 自 动 进 入 <strong>ARM</strong> 状 态 。 这 意 味 着 异 常 处 理<br />

程 序 的 第 一 部 分 必 须 用 <strong>ARM</strong> 指 令 进 行 编 码 , 即 使 它 重 新 进 入<br />

Thumb 状 态 执 行 异 常 的 主 处 理 。 在 此 类 处 理 的 末 尾 , 处 理 器 必 须 返<br />

回 <strong>ARM</strong> 状 态 , 以 便 从 处 理 程 序 返 回 主 应 用 程 序 。<br />

独 立 的 Thumb 程 序<br />

能 够 支 持 Thumb 的 <strong>ARM</strong> 处 理 器 总 是 以 <strong>ARM</strong> 状 态 启 动 。 要 在 调 试<br />

程 序 下 运 行 简 单 的 Thumb 汇 编 语 言 程 序 , 请 添 加 一 个 <strong>ARM</strong> 头 文<br />

件 , 执 行 对 Thumb 状 态 的 更 改 , 然 后 调 用 主 Thumb 例 程 。 请 参 阅<br />

第 4-6 页 的 <strong>ARM</strong> 头 文 件 示 例 的 一 个 示 例 。<br />

4.1.2 使 用 /interwork 选 项<br />

<strong>ARM</strong> 编 译 程 序 和 汇 编 程 序 中 提 供 --apcs /interwork 选 项 。 如 果 设 置 此 选 项 :<br />

• 编 译 程 序 或 汇 编 程 序 将 交 互 操 作 属 性 记 录 在 目 标 文 件 中 。<br />

• 链 接 程 序 为 子 例 程 入 口 提 供 交 互 操 作 胶 合 代 码 。<br />

• 在 汇 编 语 言 中 , 必 须 编 写 返 回 调 用 程 序 指 令 集 状 态 的 函 数 退 出 代 码 , 例 如<br />

BX lr。<br />

• 在 C 或 C++ 中 , 编 译 程 序 创 建 返 回 调 用 程 序 指 令 集 状 态 的 函 数 退 出 代 码 。<br />

• 在 C 或 C++ 中 , 编 译 程 序 将 BX 指 令 用 于 间 接 或 虚 拟 调 用 。<br />

如 果 目 标 文 件 包 括 以 下 内 容 , 请 使 用 /interwork 选 项 :<br />

• 可 能 需 要 返 回 到 <strong>ARM</strong> 代 码 的 Thumb 子 例 程 ;<br />

• 可 能 需 要 返 回 到 Thumb 代 码 的 <strong>ARM</strong> 子 例 程 ;<br />

• 可 能 间 接 或 虚 拟 调 用 <strong>ARM</strong> 代 码 的 Thumb 子 例 程 ;<br />

• 可 能 间 接 或 虚 拟 调 用 Thumb 代 码 的 <strong>ARM</strong> 子 例 程 。<br />

备 注<br />

如 果 某 个 模 块 包 含 带 有 #pragma arm 或 #pragma thumb 标 记 的 函 数 , 通 常 必 须 使 用<br />

--apcs /interwork 对 该 模 块 进 行 编 译 。 这 确 保 了 可 以 从 其 它 状 态 (<strong>ARM</strong> 或<br />

Thumb) 成 功 调 用 该 函 数 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 4-3


<strong>ARM</strong> 和 Thumb 交 互 操 作<br />

否 则 , 不 必 使 用 /interwork 选 项 。 例 如 , 目 标 文 件 中 可 能 包 括 以 下 不 需 要 /interwork<br />

选 项 的 内 容 :<br />

• 可 由 异 常 中 断 的 Thumb 代 码 。 异 常 强 制 处 理 器 进 入 <strong>ARM</strong> 状 态 , 因 而 不 需<br />

要 胶 合 代 码 。<br />

• 可 处 理 从 Thumb 代 码 发 生 的 异 常 的 处 理 代 码 。 其 返 回 不 需 要 胶 合 代 码 。<br />

• 调 用 其 它 文 件 <strong>ARM</strong> 子 例 程 的 Thumb 代 码 ( 其 交 互 操 作 返 回 序 列 属 于 被 调<br />

用 程 序 , 而 不 是 调 用 程 序 )。<br />

• 调 用 其 它 文 件 Thumb 子 例 程 的 <strong>ARM</strong> 代 码 ( 其 交 互 操 作 返 回 序 列 属 于 被 调<br />

用 程 序 , 而 不 是 调 用 程 序 )。<br />

4.1.3 检 测 交 互 操 作 调 用<br />

在 被 调 用 例 程 不 是 为 了 交 互 操 作 而 编 译 的 情 况 下 , 如 果 检 测 到 直 接 的 <strong>ARM</strong>/Thumb<br />

交 互 操 作 调 用 , 则 链 接 程 序 生 成 一 个 错 误 。 为 了 交 互 操 作 , 必 须 重 新 编 译 被 调 用 的<br />

例 程 。<br />

例 如 , 示 例 4-1 说 明 了 当 第 4-11 页 的 示 例 4-3 中 的 <strong>ARM</strong> 例 程 在 没 有 --apcs /interwork<br />

选 项 的 情 况 下 被 编 译 和 链 接 时 产 生 的 错 误 。<br />

示 例 4-1<br />

Error: L6239E: Cannot call <strong>ARM</strong> symbol 'arm_function' in non-interworking object<br />

armsub.o from THUMB code in thumbmain.o(.text)<br />

这 些 类 型 错 误 表 示 , 在 从 目 标 模 块 目 标 到 例 程 符 号 的 过 程 中 ,<strong>ARM</strong> 到 Thumb 或<br />

Thumb 到 <strong>ARM</strong> 的 交 互 操 作 调 用 被 检 测 出 来 , 但 是 , 被 调 用 的 例 程 尚 未 为 交 互 操<br />

作 而 被 编 译 。 必 须 重 新 编 译 包 含 该 符 号 的 模 块 , 并 指 定 --apcs /interwork 选 项 。<br />

4-4 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


<strong>ARM</strong> 和 Thumb 交 互 操 作<br />

4.2 汇 编 语 言 交 互 操 作<br />

在 汇 编 语 言 源 文 件 中 , 可 以 有 多 个 区 域 ( 对 应 于 ELF 段 ) 每 个 区 域 都 可 包 括<br />

<strong>ARM</strong> 指 令 、 Thumb 指 令 或 两 者 兼 而 有 之 。<br />

可 使 用 链 接 程 序 来 修 复 对 通 过 调 用 程 序 使 用 不 同 指 令 集 的 例 程 的 调 用 和 来 自 该<br />

例 程 的 返 回 。 要 执 行 此 操 作 , 请 使 用 BL 来 调 用 例 程 ( 参 阅 第 4-14 页 的 使 用 胶 合<br />

代 码 的 汇 编 语 言 交 互 操 作 )。<br />

如 果 您 愿 意 , 可 以 编 写 代 码 , 显 式 地 更 改 指 令 集 。 在 某 些 情 况 下 , 通 过 执 行 此 操<br />

作 可 编 写 更 小 更 快 的 代 码 。<br />

以 下 指 令 执 行 处 理 器 状 态 的 更 改 :<br />

• BX, 请 参 阅 跳 转 和 交 换 指 令 ;<br />

• BLX、LDR、LDM 和 POP( 仅 限 于 <strong>ARM</strong> 体 系 结 构 5 版 及 更 高 版 本 ), 请 参 阅 第<br />

4-8 页 的 <strong>ARM</strong> 体 系 结 构 5T 版 。<br />

以 下 指 令 指 示 汇 编 程 序 从 相 应 的 指 令 集 汇 编 指 令 ( 参 阅 第 4-6 页 的 更 改 汇 编 程 序<br />

模 式 ):<br />

• CODE16 ;<br />

• CODE32。<br />

4.2.1 跳 转 和 交 换 指 令<br />

BX 指 令 跳 转 到 指 定 寄 存 器 包 含 的 地 址 。 跳 转 地 址 0 位 的 值 确 定 是 否 继 续 在 <strong>ARM</strong><br />

状 态 或 Thumb 状 态 下 执 行 。 有 关 <strong>ARM</strong> 体 系 结 构 5 版 提 供 的 附 加 指 令 , 请 参 阅<br />

第 4-8 页 的 <strong>ARM</strong> 体 系 结 构 5T 版 。<br />

可 以 按 照 这 种 方 式 使 用 地 址 的 0 位 , 原 因 是 :<br />

• 所 有 的 <strong>ARM</strong> 指 令 都 是 字 对 齐 的 , 所 以 任 何 <strong>ARM</strong> 指 令 地 址 的 0 位 和 1 位 都<br />

未 被 使 用 ;<br />

• 所 有 的 Thumb 指 令 都 是 半 字 对 齐 的 , 所 以 任 何 Thumb 指 令 地 址 的 0 位 都<br />

未 被 使 用 。<br />

语 法<br />

BX 的 语 法 为 以 下 之 一 :<br />

Thumb BX Rn<br />

<strong>ARM</strong> BX{cond} Rn<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 4-5


<strong>ARM</strong> 和 Thumb 交 互 操 作<br />

其 中 :<br />

Rn<br />

是 r0 到 r15 范 围 中 的 一 个 寄 存 器 , 包 含 所 要 跳 转 的 目 标 地 址 。 此 寄<br />

存 器 中 0 位 的 值 确 定 处 理 器 的 状 态 :<br />

• 如 果 0 位 已 设 置 , 则 在 Thumb 状 态 下 执 行 跳 转 地 址 处 的 指 令 ;<br />

• 如 果 0 位 已 清 除 , 则 在 <strong>ARM</strong> 状 态 下 执 行 跳 转 地 址 处 的 指 令 。<br />

cond 是 一 个 可 选 的 条 件 码 。 仅 BX 的 <strong>ARM</strong> 版 能 被 有 条 件 地 执 行 。<br />

4.2.2 更 改 汇 编 程 序 模 式<br />

<strong>ARM</strong> 汇 编 程 序 可 汇 编 Thumb 代 码 和 <strong>ARM</strong> 代 码 。 在 默 认 情 况 下 , 它 汇 编 <strong>ARM</strong><br />

代 码 , 除 非 用 -16 选 项 调 用 。<br />

因 为 所 有 能 够 支 持 Thumb 的 <strong>ARM</strong> 处 理 器 均 以 <strong>ARM</strong> 状 态 启 动 , 所 以 , 必 须 使 用<br />

BX 指 令 跳 转 和 交 换 到 Thumb 状 态 , 然 后 使 用 CODE16 指 令 指 示 汇 编 程 序 汇 编 Thumb<br />

指 令 。 使 用 相 应 的 CODE32 指 令 指 示 汇 编 程 序 返 回 到 正 在 汇 编 的 <strong>ARM</strong> 指 令 。<br />

有 关 这 些 指 令 的 更 多 信 息 , 请 参 阅 <strong>RealView</strong> <strong>Compilation</strong> <strong>Tools</strong> 2.0 版 汇 编 程 序<br />

指 南 。<br />

4.2.3 <strong>ARM</strong> 头 文 件 示 例<br />

第 4-7 页 的 示 例 4-2 包 括 四 段 代 码 。 第 一 段 实 现 将 处 理 器 更 改 到 Thumb 状 态 所 需<br />

的 <strong>ARM</strong> 代 码 小 头 文 件 段 。<br />

头 文 件 代 码 使 用 :<br />

• 装 载 跳 转 地 址 并 设 置 最 低 有 效 位 的 ADR 伪 指 令 。 该 ADR 伪 指 令 通 过 用<br />

pc+offset+1 装 载 r0 来 生 成 地 址 。 有 关 ADR 伪 指 令 的 更 多 信 息 , 请 参 阅<br />

<strong>RealView</strong> <strong>Compilation</strong> <strong>Tools</strong> 2.0 版 汇 编 程 序 指 南 。<br />

• 跳 转 到 Thumb 代 码 并 更 改 处 理 器 状 态 的 BX 指 令 。<br />

该 模 块 的 第 二 段 ( 标 记 为 ThumbProg), 由 CODE16 指 令 加 上 前 缀 , 而 该 指 令 指 示<br />

汇 编 程 序 将 以 下 代 码 视 为 为 Thumb 代 码 。Thumb 代 码 将 两 个 寄 存 器 的 内 容 合 在<br />

一 起 。<br />

处 理 器 被 更 改 回 <strong>ARM</strong> 状 态 。 代 码 再 次 使 用 ADR 指 令 来 获 取 标 签 的 地 址 , 但 是 ,<br />

这 次 最 低 有 效 位 没 有 被 使 用 。 BX 指 令 更 改 其 状 态 。<br />

4-6 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


<strong>ARM</strong> 和 Thumb 交 互 操 作<br />

第 三 段 代 码 将 两 个 寄 存 器 的 内 容 合 在 一 起 。<br />

最 后 一 段 标 记 为 stop 的 代 码 使 用 半 主 机 的 SWI 来 报 告 应 用 程 序 的 正 常 退 出 。<br />

有 关 半 主 机 的 更 多 信 息 , 请 参 阅 <strong>RealView</strong> <strong>Compilation</strong> <strong>Tools</strong> 2.0 版 编 译 程 序 和<br />

库 指 南 。<br />

备 注<br />

该 Thumb 半 主 机 SWI 的 编 号 不 同 于 <strong>ARM</strong> 半 主 机 SWI ( 是 0xAB 而 不 是 0x123456)。<br />

示 例 4-2<br />

AREA AddReg,CODE,READONLY ; Name this block of code.<br />

ENTRY<br />

; Mark first instruction to call.<br />

main<br />

ADR r0, ThumbProg + 1<br />

BX r0<br />

; Generate branch target address<br />

; and set bit 0, hence arrive<br />

; at target in Thumb state.<br />

; Branch exchange to ThumbProg.<br />

CODE16<br />

; Subsequent instructions are Thumb code.<br />

ThumbProg<br />

MOV r2, #2 ; Load r2 with value 2.<br />

MOV r3, #3 ; Load r3 with value 3.<br />

ADD r2, r2, r3<br />

; r2 = r2 + r3<br />

ADR r0, <strong>ARM</strong>Prog<br />

BX r0<br />

CODE32<br />

; Subsequent instructions are <strong>ARM</strong> code.<br />

<strong>ARM</strong>Prog<br />

MOV r4, #4<br />

MOV r5, #5<br />

ADD r4, r4, r5<br />

stop MOV r0, #0x18<br />

LDR r1, =0x20026<br />

SWI 0x123456<br />

END<br />

; angel_SWIreason_ReportException<br />

; ADP_Stopped_ApplicationExit<br />

; <strong>ARM</strong> semihosting SWI<br />

; Mark end of this file.<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 4-7


<strong>ARM</strong> 和 Thumb 交 互 操 作<br />

编 译 示 例<br />

编 译 并 执 行 示 例 :<br />

1. 使 用 任 何 文 本 编 辑 器 输 入 代 码 并 将 文 件 保 存 为 addreg.s。<br />

2. 在 命 令 提 示 行 键 入 armasm -g addreg.s 来 汇 编 源 文 件 。<br />

3. 键 入 armlink addreg.o -o addreg 链 接 该 文 件 。<br />

4. 将 ELF/DWARF2 兼 容 调 试 器 与 相 应 调 试 目 标 配 合 使 用 , 运 行 映 象 。 如 果 每<br />

次 一 条 指 令 地 执 行 程 序 , 会 看 到 处 理 器 进 入 Thumb 状 态 。 参 阅 所 使 用 的 调<br />

试 器 用 户 文 档 , 找 出 指 示 此 变 更 的 方 法 。<br />

4.2.4 <strong>ARM</strong> 体 系 结 构 5T 版<br />

在 <strong>ARM</strong> 体 系 结 构 5T 版 及 更 高 版 本 中 :<br />

• 以 下 额 外 的 交 互 操 作 指 令 可 用 :<br />

BLX address<br />

处 理 器 执 行 一 个 与 PC 相 关 的 跳 转 , 转 到 含 有 链 接 的 address 并 更<br />

改 状 态 。address 必 须 在 <strong>ARM</strong> 代 码 下 PC 的 32MB 之 内 , 在<br />

Thumb 代 码 下 PC 的 4MB 之 内 。<br />

BLX register<br />

处 理 器 执 行 含 有 链 接 的 跳 转 , 转 到 指 定 寄 存 器 包 含 的 地 址 。[0] 位<br />

的 值 确 定 新 的 处 理 器 状 态 。<br />

在 每 种 情 况 下 ,lr 的 [0] 位 均 设 置 成 CPSR 中 Thumb 位 的 当 前 值 。 这 意 味 着<br />

返 回 指 令 可 以 自 动 返 回 正 确 的 处 理 器 状 态 。<br />

• 如 果 LDR、LDM 或 POP 载 入 PC, 它 们 将 CPSR 中 的 Thumb 位 设 置 成 载 入 PC<br />

的 值 的 [0] 位 。 可 以 使 用 此 项 来 更 改 指 令 集 。 对 于 从 子 例 程 返 回 , 这 尤 其<br />

有 用 。 相 同 的 返 回 指 令 可 以 返 回 到 <strong>ARM</strong> 调 用 程 序 , 也 可 以 返 回 到 Thumb<br />

调 用 程 序 。<br />

有 关 更 多 信 息 , 请 参 阅 <strong>RealView</strong> <strong>Compilation</strong> <strong>Tools</strong> 2.0 版 编 译 程 序 指 南 和 <strong>ARM</strong> 体<br />

系 结 构 参 考 手 册 。<br />

4-8 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


<strong>ARM</strong> 和 Thumb 交 互 操 作<br />

4.2.5 Thumb 代 码 中 的 标 签<br />

链 接 程 序 区 别 引 用 以 下 内 容 的 标 签 :<br />

• <strong>ARM</strong> 指 令 ;<br />

• Thumb 指 令 ;<br />

• 数 据 。<br />

当 链 接 程 序 重 定 位 一 个 引 用 Thumb 指 令 的 标 签 的 值 时 , 它 将 最 低 有 效 位 设 置 成<br />

该 重 定 位 值 。 这 意 味 着 到 标 签 的 跳 转 可 自 动 选 择 相 应 的 指 令 集 。 如 果 将 以 下 任 何<br />

指 令 用 于 跳 转 , 这 都 可 实 现 :<br />

• <strong>ARM</strong> 体 系 结 构 4T 版 中 的 BX ;<br />

• 体 系 结 构 5T 版 及 更 高 版 本 中 的 BX、 BLX 或 LDR。<br />

在 早 于 1.2 和 SDT 的 ADS 版 本 中 , 将 Thumb 代 码 中 的 数 据 标 记 上 DATA 指 令 是<br />

必 要 的 。 现 在 , 这 不 再 必 要 了 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 4-9


<strong>ARM</strong> 和 Thumb 交 互 操 作<br />

4.3 C 和 C++ 交 互 操 作 和 胶 合 代 码<br />

可 以 自 由 地 混 合 为 <strong>ARM</strong> 和 Thumb 而 编 译 的 C 和 C++ 代 码 , 但 是 , 在 <strong>ARM</strong> 体<br />

系 结 构 4T 版 中 ,<strong>ARM</strong> 和 Thumb 代 码 之 间 需 要 一 小 段 称 为 胶 合 代 码 的 代 码 , 才<br />

能 执 行 状 态 更 改 。<strong>ARM</strong> 链 接 程 序 在 检 测 到 交 互 操 作 调 用 时 生 成 这 些 交 互 操 作 胶<br />

合 代 码 。<br />

4.3.1 为 交 互 操 作 编 译 代 码<br />

--apcs /interwork 编 译 程 序 选 项 使 <strong>ARM</strong> 编 译 程 序 能 够 编 译 包 括 例 程 的 C 和 C++<br />

模 块 , 而 该 例 程 可 以 由 其 它 处 理 器 状 态 编 译 的 例 程 进 行 调 用 :<br />

armcc --thumb --apcs /interwork<br />

armcc --arm --apcs /interwork<br />

armcc --cpp --thumb --apcs /interwork<br />

armcc --cpp --arm --apcs /interwork<br />

备 注<br />

--arm 为 默 认 选 项 。<br />

为 <strong>ARM</strong> 体 系 结 构 4T 版 上 交 互 操 作 而 编 译 的 模 块 生 成 稍 大 的 代 码 , 通 常 对 于<br />

Thumb 大 2%, 对 于 <strong>ARM</strong> 大 1% 以 下 。 对 于 <strong>ARM</strong> 体 系 结 构 5 版 没 有 区 别 。<br />

在 叶 函 数 ( 其 函 数 体 不 包 含 函 数 的 调 用 ) 中 , 由 编 译 程 序 生 成 的 代 码 的 唯 一 更<br />

改 是 用 BX lr 替 换 MOV pc,lr。 MOV 指 令 不 造 成 必 要 的 状 态 更 改 。<br />

在 Thumb 模 式 下 为 <strong>ARM</strong> 体 系 结 构 4T 版 而 编 译 的 非 叶 函 数 中 , 编 译 程 序 必 须 替<br />

换 单 个 指 令 ( 举 例 说 明 ):<br />

POP {r4,r5,pc}<br />

成 为 序 列 :<br />

POP {r4,r5}<br />

POP {r3}<br />

BX r3<br />

这 对 性 能 有 一 点 影 响 。 为 交 互 操 作 编 译 所 有 源 模 块 , 除 非 能 够 确 保 它 们 永 远 不 会<br />

用 于 交 互 操 作 。<br />

--apcs /interwork 选 项 还 为 编 译 模 块 的 目 标 代 码 区 域 而 设 置 交 互 操 作 属 性 。 链 接<br />

程 序 检 测 此 属 性 并 插 入 相 应 的 胶 合 代 码 。<br />

4-10 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


<strong>ARM</strong> 和 Thumb 交 互 操 作<br />

备 注<br />

为 交 互 操 作 而 编 译 的 <strong>ARM</strong> 代 码 只 能 用 于 <strong>ARM</strong> 体 系 结 构 4T 版 及 更 高 版 本 , 因<br />

为 早 期 的 处 理 器 不 实 现 BX 指 令 。<br />

使 用 armlink -info veneers 选 项 查 找 胶 合 代 码 所 占 空 间 的 大 小 。<br />

C 交 互 操 作 示 例<br />

示 例 4-3 说 明 执 行 <strong>ARM</strong> 子 例 程 交 互 操 作 调 用 的 一 个 Thumb 例 程 。<strong>ARM</strong> 子 例 程 的<br />

调 用 对 Thumb 库 中 的 printf() 进 行 交 互 操 作 调 用 。 这 两 个 模 块 作 为 thumbmain.c 和<br />

armsub.c, 在 Examples_directory\interwork 中 提 供 。<br />

示 例 4-3<br />

/*********************<br />

* thumbmain.c *<br />

**********************/<br />

#include <br />

extern void arm_function(void);<br />

int main(void)<br />

{<br />

printf("Hello from Thumb World\n");<br />

arm_function();<br />

printf("And goodbye from Thumb World\n");<br />

return (0);<br />

}<br />

/*********************<br />

* armsub.c *<br />

**********************/<br />

#include <br />

void arm_function(void)<br />

{<br />

printf("Hello and Goodbye from <strong>ARM</strong> world\n");<br />

}<br />

编 译 并 链 接 这 些 模 块 :<br />

1. 在 系 统 提 示 行 键 入 armcc --thumb -c --apcs /interwork -o thumbmain.o<br />

thumbmain.c, 为 交 互 操 作 编 译 Thumb 代 码 。<br />

2. 在 系 统 提 示 行 键 入 armcc -c --apcs /interwork -o armsub.o armsub.c, 为 交 互<br />

操 作 编 译 <strong>ARM</strong> 代 码 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 4-11


<strong>ARM</strong> 和 Thumb 交 互 操 作<br />

3. 键 入 armlink thumbmain.o armsub.o -o thumbtoarm.axf 链 接 目 标 文 件 。<br />

或 者 , 查 看 交 互 操 作 胶 合 代 码 ( 示 例 4-4) 的 大 小 :<br />

armlink armsub.o thumbmain.o -o thumbtoarm.axf -info veneers<br />

示 例 4-4<br />

Adding Veneers to the image<br />

Adding TA veneer (4 bytes, Inline) for call to 'arm_function' from thumbmain.o(.text).<br />

Adding AT veneer (8 bytes, Inline) for call to '_printf' from armsub.o(.text).<br />

Adding TA veneer (4 bytes, Inline) for call to '_ll_cmpge' from __vfpntf.o(.text).<br />

Adding TA veneer (4 bytes, Inline) for call to '_ll_neg' from __vfpntf.o(.text).<br />

Adding TA veneer (4 bytes, Inline) for call to '_fp_display_gate' from __vfpntf.o(.text).<br />

Adding TA veneer (4 bytes, Inline) for call to '_ll_ushift_r' from __vfpntf.o(.text).<br />

Adding TA veneer (4 bytes, Inline) for call to '_ll_cmpu' from __vfpntf.o(.text).<br />

Adding TA veneer (4 bytes, Inline) for call to '_ll_udiv10' from __vfpntf.o(.text).<br />

Adding TA veneer (4 bytes, Inline) for call to '__rt_udiv10' from __vfpntf.o(.text).<br />

Adding AT veneer (8 bytes, Inline) for call to '__rt_lib_init' from kernel.o(.text).<br />

Adding AT veneer (12 bytes, Long) for call to '__rt_lib_shutdown' from kernel.o(.text).<br />

Adding TA veneer (4 bytes, Inline) for call to '__rt_memclr_w' from stdio.o(.text).<br />

Adding TA veneer (4 bytes, Inline) for call to '__rt_raise' from stdio.o(.text).<br />

Adding TA veneer (8 bytes, Short) for call to '__rt_exit' from exit.o(.text).<br />

Adding TA veneer (4 bytes, Inline) for call to '__user_libspace' from free.o(.text).<br />

Adding TA veneer (4 bytes, Inline) for call to '_fp_init' from lib_init.o(.text).<br />

Adding TA veneer (4 bytes, Inline) for call to '__heap_extend' from malloc.o(.text).<br />

Adding AT veneer (8 bytes, Inline) for call to '__raise' from rt_raise.o(.text).<br />

Adding TA veneer (4 bytes, Inline) for call to '__rt_errno_addr' from ftell.o(.text).<br />

Adding AT veneer (8 bytes, Inline) for call to '_no_fp_display' from printf2.o(x$fpl$printf2).<br />

20 Veneer(s) (total 108 bytes) added to the image.<br />

4-12 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


<strong>ARM</strong> 和 Thumb 交 互 操 作<br />

4.3.2 交 互 操 作 的 基 本 规 则<br />

4.3.3 使 用 同 一 函 数 的 两 个 副 本<br />

下 列 规 则 应 用 于 应 用 程 序 之 内 的 交 互 操 作 :<br />

• 必 须 使 用 --apcs /interwork 命 令 行 选 项 , 编 译 任 何 包 含 可 能 返 回 其 它 指 令<br />

集 的 C 或 C++ 模 块 。<br />

• 必 须 使 用 --apcs /interwork 命 令 行 选 项 , 编 译 任 何 包 含 可 能 间 接 或 虚 拟 调<br />

用 其 它 指 令 集 函 数 的 C 或 C++ 模 块 。<br />

• 永 远 不 要 从 其 它 状 态 的 代 码 中 间 接 调 用 非 交 互 操 作 代 码 , 如 使 用 函 数 指 针<br />

的 调 用 。<br />

• 如 果 输 入 对 象 包 含 Thumb 代 码 , 则 链 接 程 序 选 择 Thumb 运 行 时 的 库 。 这<br />

些 为 交 互 操 作 而 编 译 。<br />

如 果 在 链 接 程 序 命 令 行 中 显 式 地 指 定 自 己 的 库 中 的 一 个 库 , 必 须 确 保 它 是<br />

一 个 合 适 的 交 互 操 作 库 。<br />

可 以 有 两 个 名 字 相 同 的 函 数 , 一 个 编 译 成 <strong>ARM</strong>, 另 一 个 编 译 成 Thumb, 但 是 ,<br />

不 建 议 这 样 做 。 在 绝 大 多 数 情 况 下 , 这 并 不 能 明 显 地 增 加 性 能 。<br />

备 注<br />

两 个 版 本 的 函 数 必 须 用 --apcs /interwork 选 项 进 行 编 译 。 这 是 因 为 不 能 保 证 只 从<br />

Thumb 状 态 调 用 Thumb 版 本 的 函 数 和 只 从 <strong>ARM</strong> 状 态 调 用 <strong>ARM</strong> 版 本 的 函 数 。<br />

链 接 程 序 启 用 重 复 定 义 , 其 条 件 是 一 个 定 义 定 义 Thumb 例 程 , 另 一 个 则 定 义<br />

<strong>ARM</strong> 例 程 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 4-13


<strong>ARM</strong> 和 Thumb 交 互 操 作<br />

4.4 使 用 胶 合 代 码 的 汇 编 语 言 交 互 操 作<br />

第 4-5 页 的 汇 编 语 言 交 互 操 作 中 介 绍 的 汇 编 语 言 <strong>ARM</strong>/Thumb 交 互 操 作 方 法 ,<br />

执 行 了 所 有 必 要 的 中 间 处 理 。 对 于 链 接 程 序 插 入 交 互 操 作 胶 合 代 码 , 没 有 任 何<br />

要 求 。<br />

本 节 介 绍 如 何 利 用 胶 合 代 码 进 行 :<br />

• 汇 编 语 言 模 块 之 间 的 交 互 操 作 ;<br />

• 汇 编 语 言 和 C 或 C++ 模 块 之 间 的 交 互 操 作 。<br />

4.4.1 使 用 胶 合 代 码 的 汇 编 间 交 互 调 用<br />

可 编 写 汇 编 语 言 <strong>ARM</strong>/Thumb 交 互 操 作 代 码 , 使 用 链 接 程 序 生 成 的 交 互 操 作 胶 合<br />

代 码 。 要 执 行 此 操 作 , 需 编 写 :<br />

• 一 个 象 任 何 非 交 互 操 作 例 程 的 调 用 例 程 , 使 用 BL 指 令 来 进 行 调 用 。 调 用<br />

例 程 可 通 过 --apcs /interwork 或 --apcs /nointerwork 来 进 行 汇 编 。<br />

• 使 用 BX 指 令 返 回 的 被 调 用 例 程 。 被 调 用 例 程 必 须 用 --apcs /interwork 来 进<br />

行 汇 编 。<br />

通 常 只 有 在 <strong>ARM</strong> 体 系 结 构 4T 版 中 , 或 调 用 程 序 和 被 调 用 程 序 分 布 广 泛 或 在 不<br />

同 的 区 域 中 时 , 这 才 是 必 要 的 。 在 <strong>ARM</strong> 体 系 结 构 5T 版 中 , 如 果 调 用 程 序 和 被<br />

调 用 程 序 距 离 足 够 近 , 则 无 需 胶 合 代 码 。<br />

4-14 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


<strong>ARM</strong> 和 Thumb 交 互 操 作<br />

使 用 胶 合 代 码 的 汇 编 语 言 交 互 操 作 的 示 例<br />

示 例 4-5 说 明 了 将 寄 存 器 r0 到 r2 分 别 设 置 为 1、2 和 3 的 代 码 。 寄 存 器 r0 和 r2<br />

由 <strong>ARM</strong> 代 码 设 置 。 r1 由 Thumb 代 码 设 置 。 请 注 意 :<br />

• 该 代 码 必 须 用 --apcs /interwork 选 项 来 进 行 汇 编 ;<br />

• 使 用 BX lr 指 令 从 子 例 程 中 返 回 , 而 不 是 通 常 的 MOV pc,lr。<br />

示 例 4-5<br />

; *****<br />

; arm.s<br />

; *****<br />

AREA Arm,CODE,READONLY ; Name this block of code.<br />

IMPORT ThumbProg<br />

ENTRY<br />

; Mark 1st instruction to call.<br />

<strong>ARM</strong>Prog<br />

MOV r0,#1<br />

; Set r0 to show in <strong>ARM</strong> code.<br />

BL ThumbProg ; Call Thumb subroutine.<br />

MOV r2,#3<br />

; Set r2 to show returned to <strong>ARM</strong>.<br />

; Terminate execution.<br />

MOV r0, #0x18<br />

; angel_SWIreason_ReportException<br />

LDR r1, =0x20026<br />

; ADP_Stopped_ApplicationExit<br />

SWI 0x123456<br />

; <strong>ARM</strong> semihosting SWI<br />

END<br />

; *******<br />

; thumb.s<br />

; *******<br />

AREA Thumb,CODE,READONLY ; Name this block of code.<br />

CODE16<br />

; Subsequent instructions are Thumb.<br />

EXPORT ThumbProg<br />

ThumbProg<br />

MOV r1, #2<br />

; Set r1 to show reached Thumb code.<br />

BX lr ; Return to <strong>ARM</strong> subroutine.<br />

END<br />

; Mark end of this file.<br />

按 照 这 些 步 骤 编 译 并 链 接 模 块 , 然 后 检 查 交 互 操 作 胶 合 代 码 :<br />

1. 键 入 armasm arm.s 来 汇 编 <strong>ARM</strong> 代 码 。<br />

2. 键 入 armasm -16 --apcs /interwork thumb.s 来 汇 编 Thumb 代 码 。<br />

3. 键 入 armlink arm.o thumb.o -o count 来 链 接 两 个 目 标 文 件 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 4-15


<strong>ARM</strong> 和 Thumb 交 互 操 作<br />

4. 将 ELF/DWARF2 兼 容 调 试 器 与 相 应 调 试 目 标 配 合 使 用 , 运 行 映 象 。<br />

4.4.2 使 用 胶 合 代 码 的 C、 C++ 和 汇 编 语 言 交 互 操 作<br />

编 译 后 在 某 一 状 态 下 运 行 的 C 和 C++ 代 码 , 可 以 调 用 设 计 在 其 它 状 态 下 运 行 的<br />

汇 编 语 言 代 码 , 反 之 亦 然 。 要 执 行 此 操 作 , 请 编 写 调 用 例 程 作 为 非 交 互 操 作 例<br />

程 , 并 且 在 通 过 汇 编 语 言 进 行 调 用 时 , 使 用 BL 指 令 来 进 行 调 用 ( 参 阅 示 例<br />

4-6)。 然 后 :<br />

• 如 果 被 调 用 例 程 是 用 C 语 言 编 写 的 , 请 用 --apcs /interwork 来 进 行 汇 编 ;<br />

• 如 果 被 调 用 例 程 是 用 汇 编 语 言 编 写 的 , 请 用 --apcs /interwork 选 项 来 进 行<br />

汇 编 , 用 BX lr 来 返 回 。<br />

备 注<br />

使 用 此 方 式 的 任 何 汇 编 语 言 或 用 户 库 代 码 , 必 须 在 相 应 处 与 ATPCS 保 持 一 致 。<br />

示 例 4-6<br />

/**********************<br />

* thumb.c *<br />

**********************/<br />

#include <br />

extern int arm_function(int);<br />

int main(void)<br />

{<br />

int i = 1;<br />

printf("i = %d\n", i);<br />

printf("And now i = %d\n", arm_function(i));<br />

return (0);<br />

}<br />

; *****<br />

; arm.s<br />

; *****<br />

AREA Arm,CODE,READONLY ; Name this block of code.<br />

EXPORT arm_function<br />

arm_function<br />

ADD r0,r0,#4 ; Add 4 to first parameter.<br />

BX lr ; Return<br />

END<br />

4-16 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


<strong>ARM</strong> 和 Thumb 交 互 操 作<br />

按 照 这 些 步 骤 编 译 并 链 接 模 块 :<br />

1. 键 入 armcc --thumb -c --apcs /interwork thumb.c 来 汇 编 Thumb 代 码 。<br />

2. 键 入 armasm --apcs /interwork arm.s 来 汇 编 <strong>ARM</strong> 代 码 。<br />

3. 键 入 armlink arm.o thumb.o -o add 来 链 接 两 个 目 标 文 件 。<br />

4. 将 ELF/DWARF2 兼 容 调 试 器 与 相 应 调 试 目 标 配 合 使 用 , 运 行 映 象 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 4-17


<strong>ARM</strong> 和 Thumb 交 互 操 作<br />

4-18 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


第 5 章<br />

混 合 使 用 C、 C++ 和 汇 编 语 言<br />

本 章 描 述 如 何 编 写 C、C++ 和 <strong>ARM</strong> 汇 编 语 言 混 合 代 码 。 还 描 述 如 何 从 C 和 C++<br />

使 用 <strong>ARM</strong> 内 联 和 嵌 入 式 汇 编 程 序 。 它 包 含 以 下 几 个 部 分 :<br />

• 第 5-2 页 的 使 用 内 联 汇 编 程 序 ;<br />

• 第 5-12 页 的 使 用 嵌 入 式 汇 编 程 序 ;<br />

• 第 5-15 页 的 内 联 汇 编 代 码 与 嵌 入 式 汇 编 代 码 之 间 的 差 异 ;<br />

• 第 5-16 页 的 从 汇 编 代 码 访 问 C 全 局 变 量 ;<br />

• 第 5-17 页 的 在 C++ 中 使 用 C 头 文 件 ;<br />

• 第 5-19 页 的 C、C++ 和 <strong>ARM</strong> 汇 编 语 言 之 间 的 调 用 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 5-1


混 合 使 用 C、 C++ 和 汇 编 语 言<br />

5.1 使 用 内 联 汇 编 程 序<br />

<strong>ARM</strong> 编 译 程 序 内 建 的 内 联 汇 编 程 序 使 您 可 以 使 用 不 能 从 C 直 接 访 问 的 目 标 处 理<br />

器 功 能 。 例 如 :<br />

• 饱 和 算 法 ( 请 参 阅 <strong>RealView</strong> 编 译 工 具 2.0 版 汇 编 程 序 指 南 );<br />

• 定 制 协 处 理 器 ;<br />

• PSR。<br />

内 联 汇 编 程 序 支 持 与 C 和 C++ 非 常 灵 活 的 交 互 。 任 何 寄 存 器 操 作 数 都 可 以 是<br />

任 意 的 C 或 C++ 表 达 式 。 内 联 汇 编 程 序 还 扩 展 了 复 杂 指 令 , 并 优 化 了 汇 编 语<br />

言 代 码 。<br />

备 注<br />

如 果 默 认 情 况 下 , 或 者 用 -O1 或 -O2 编 译 程 序 选 项 启 用 了 优 化 , 则 内 联 汇 编 语 言<br />

将 由 编 译 程 序 进 行 优 化 。<br />

<strong>ARM</strong> 代 码 内 联 汇 编 程 序 实 现 了 <strong>ARM</strong> 指 令 集 中 的 大 多 数 指 令 , 包 括 一 般 协 处 理<br />

器 指 令 、 半 字 指 令 和 长 乘 法 。<br />

备 注<br />

在 RVCT v2.0 中 不 支 持 Thumb 代 码 内 联 汇 编 程 序 。<br />

有 关 限 制 的 信 息 , 请 参 阅 第 5-7 页 的 内 联 汇 编 程 序 和 armasm 的 不 同 点 。<br />

内 联 汇 编 程 序 是 一 个 高 级 汇 编 程 序 。 它 生 成 的 代 码 与 您 所 生 成 的 代 码 并 不 总 是<br />

完 全 一 致 。 不 能 用 它 来 生 成 比 编 译 程 序 生 成 代 码 更 有 效 的 代 码 。 应 当 使 用 <strong>ARM</strong><br />

汇 编 程 序 armasm 来 实 现 此 目 的 。<br />

不 支 持 <strong>ARM</strong> 汇 编 程 序 armasm 可 以 使 用 的 某 些 低 级 功 能 , 如 不 能 通 过 写 入 PC 进<br />

行 跳 转 。<br />

有 关 内 联 汇 编 程 序 的 详 细 信 息 , 请 参 阅 <strong>RealView</strong> 编 译 工 具 2.0 版 编 译 程 序 和 库<br />

指 南 中 关 于 内 联 和 嵌 入 式 汇 编 程 序 一 章 。<br />

5-2 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


混 合 使 用 C、C++ 和 汇 编 语 言<br />

5.1.1 调 用 内 联 汇 编 程 序<br />

如 何 调 用 内 联 汇 编 程 序 取 决 于 编 译 的 是 C 还 是 C++:<br />

• 编 译 C 时 , <strong>ARM</strong> 编 译 程 序 通 过 __asm 说 明 符 支 持 内 联 汇 编 语 言 。<br />

• 编 译 C++ 时 ,<strong>ARM</strong> 编 译 程 序 通 过 __asm 说 明 符 和 asm 关 键 字 支 持 内 联 汇 编<br />

语 言 。<br />

有 关 内 联 汇 编 程 序 的 详 细 信 息 , 请 参 阅 <strong>RealView</strong> 编 译 工 具 2.0 版 编 译 程 序 和 库<br />

指 南 中 关 于 内 联 和 嵌 入 式 汇 编 程 序 一 章 。<br />

带 有 __asm 说 明 符 的 内 联 汇 编 程 序<br />

编 译 C 或 C++ 时 , 可 以 通 过 __asm 汇 编 程 序 说 明 符 调 用 内 联 汇 编 程 序 。 说 明 符<br />

后 面 跟 随 有 一 列 包 含 在 大 括 号 中 的 汇 编 程 序 指 令 。 例 如 :<br />

__asm<br />

{<br />

instruction [; instruction]<br />

...<br />

[instruction]<br />

}<br />

如 果 两 条 指 令 在 同 一 行 中 , 必 须 用 分 号 将 其 分 隔 。 如 果 一 条 指 令 占 用 多 行 , 必<br />

须 用 反 斜 线 符 号 (\) 指 定 续 行 。 可 在 内 联 汇 编 语 言 块 内 的 任 意 位 置 处 使 用 C 或<br />

C++ 注 释 。<br />

可 在 任 何 可 以 使 用 C 或 C++ 语 句 的 地 方 使 用 __asm 语 句 。<br />

带 有 asm 关 键 字 的 内 联 汇 编 程 序<br />

编 译 C++ 时 ,<strong>ARM</strong> 编 译 程 序 支 持 ISO C++ 标 准 中 建 议 的 asm 语 法 , 其 限 制 是 字<br />

符 串 文 字 必 须 是 单 个 字 符 串 。 例 如 :<br />

asm("instruction[;instruction]");<br />

asm 语 句 必 须 在 C++ 函 数 内 。 字 符 串 文 字 中 不 能 包 括 注 释 。 可 在 任 何 可 以 使 用 C<br />

或 C++ 语 句 的 地 方 使 用 asm 语 句 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 5-3


混 合 使 用 C、 C++ 和 汇 编 语 言<br />

用 内 联 汇 编 代 码 实 现 加 法 示 例<br />

示 例 5-1 显 示 使 用 内 联 汇 编 代 码 将 两 个 值 相 加 的 示 例 。 将 它 与 第 5-13 页 的 示 例<br />

5-4 中 的 嵌 入 式 汇 编 函 数 进 行 比 较 。<br />

示 例 5-1 用 内 联 汇 编 代 码 实 现 加 法<br />

#include <br />

void main() {<br />

int r0=12345;<br />

int r1=67890;<br />

int res;<br />

__asm {<br />

ADD res, r0, r1<br />

registers),<br />

}<br />

// r0 and r1 are C/C++ variables (virtual<br />

// not the physical registers<br />

}<br />

printf("12345 + 67890 = %d\n", res);<br />

5.1.2 <strong>ARM</strong> 指 令 集<br />

<strong>ARM</strong> 指 令 集 在 <strong>ARM</strong> 体 系 结 构 参 考 手 册 中 描 述 。 所 有 指 令 操 作 码 和 寄 存 器 说 明<br />

符 都 可 以 用 小 写 或 大 写 字 母 表 达 。<br />

操 作 数 表 达 式<br />

任 何 寄 存 器 或 常 数 操 作 数 可 以 是 任 意 C 或 C++ 表 达 式 , 因 此 可 以 读 写 变 量 。 表<br />

达 式 必 须 是 整 型 可 分 配 的 , 即 char、short、int 或 long 型 。 对 char 和 short 型 不<br />

执 行 符 号 扩 展 。 您 必 须 对 这 些 类 型 明 确 执 行 符 号 扩 展 。 编 译 程 序 可 能 会 添 加 代<br />

码 , 以 计 算 这 些 表 达 式 并 将 它 们 分 配 给 寄 存 器 。<br />

当 操 作 数 用 作 目 标 时 , 表 达 式 必 须 是 可 赋 值 的 。 编 写 同 时 使 用 物 理 寄 存 器 和 表 达<br />

式 的 代 码 时 必 须 小 心 , 不 要 使 用 需 要 计 算 很 多 寄 存 器 的 复 杂 表 达 式 。 如 果 编 译 程<br />

序 在 分 配 寄 存 器 时 检 测 到 冲 突 , 将 发 出 错 误 信 息 。<br />

5-4 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


混 合 使 用 C、C++ 和 汇 编 语 言<br />

虚 拟 和 物 理 寄 存 器<br />

内 联 汇 编 程 序 提 供 对 <strong>ARM</strong> 处 理 器 物 理 寄 存 器 的 非 直 接 访 问 。 如 果 使 用 <strong>ARM</strong> 寄<br />

存 器 名 作 为 内 联 汇 编 程 序 指 令 的 操 作 数 , 则 它 总 是 表 示 虚 拟 寄 存 器 , 而 不 是 物 理<br />

<strong>ARM</strong> 整 型 寄 存 器 。<br />

在 优 化 和 代 码 生 成 过 程 中 ,<strong>ARM</strong> 编 译 程 序 给 每 个 虚 拟 寄 存 器 分 配 相 应 的 物 理 寄<br />

存 器 。 然 而 , 汇 编 代 码 中 使 用 的 物 理 寄 存 器 可 能 与 在 指 令 中 指 定 的 不 同 。 可 将 这<br />

些 虚 拟 寄 存 器 显 式 定 义 为 标 准 C 或 C++ 变 量 。 如 果 这 些 虚 拟 寄 存 器 未 定 义 , 编<br />

译 程 序 会 为 它 们 提 供 隐 式 定 义 。<br />

不 能 为 PC (r15)、 lr (r14) 和 sp (r13) 寄 存 器 创 建 虚 拟 寄 存 器 , 而 且 不 能 在 内 联 汇<br />

编 代 码 中 读 取 或 直 接 修 改 它 们 。 任 何 试 图 使 用 这 些 寄 存 器 的 操 作 都 会 导 致 出 现<br />

错 误 消 息 。<br />

不 存 在 虚 拟 处 理 器 状 态 寄 存 器 (PSR)。 任 何 对 PSR 的 引 用 总 是 指 向 物 理 PSR。<br />

备 注<br />

每 个 虚 拟 寄 存 器 中 的 初 值 是 不 可 预 测 的 。 必 须 在 读 取 之 前 将 初 值 写 入 虚 拟 寄 存<br />

器 。 如 果 在 写 入 之 前 试 图 读 虚 拟 寄 存 器 , 编 译 程 序 会 给 予 警 告 。<br />

常 数<br />

常 数 表 达 式 说 明 符 # 是 可 选 的 。 如 果 使 用 了 它 , 其 后 的 表 达 式 必 须 是 常 数 。<br />

指 令 扩 展<br />

带 有 常 数 操 作 的 指 令 中 的 常 数 不 仅 仅 局 限 于 该 指 令 所 允 许 的 值 。 这 样 的 指 令 能<br />

数 用 作 目 标 时<br />

够 被 解 释 为 具 有 同 等 效 果 的 指 令 序 列 。 例 如 :<br />

ADD r0, r0, #1023<br />

可 能 解 释 为 :<br />

ADD r0, r0, #1024<br />

SUB r0, r0, #1<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 5-5


混 合 使 用 C、 C++ 和 汇 编 语 言<br />

除 了 协 处 理 器 指 令 之 外 , 所 有 带 有 常 数 操 作 数 的 <strong>ARM</strong> 指 令 都 支 持 指 令 扩 展 。<br />

此 外 , 当 MUL 指 令 的 第 三 个 操 作 数 是 常 数 时 , 该 指 令 可 以 扩 展 为 一 系 列 加 法 和<br />

移 位 指 令 。<br />

用 扩 展 指 令 更 新 CPSR 的 效 果 是 :<br />

• 算 法 指 令 正 确 设 置 NZCV 标 志 。<br />

• 逻 辑 指 令 :<br />

— 正 确 设 置 NZ 标 志 ;<br />

— 不 改 变 V 标 志 ;<br />

— 破 坏 C 标 志 。<br />

标 号<br />

在 内 联 汇 编 程 序 语 句 中 可 以 使 用 C 和 C++ 标 号 。 只 能 用 以 下 格 式 通 过 跳 转 指 令<br />

跳 转 到 C 和 C++ 标 号 :<br />

B{cond} label<br />

存 储 器 声 明<br />

所 有 存 储 器 都 可 以 用 C 或 C++ 进 行 声 明 , 并 使 用 变 量 传 递 给 内 联 汇 编 程 序 。 因<br />

此 , 未 实 现 由 armasm 支 持 的 存 储 器 声 明 。<br />

SWI 和 BL 指 令<br />

利 用 内 联 汇 编 程 序 的 SWI 和 BL 指 令 , 可 在 常 规 指 令 字 段 后 指 定 3 个 可 选 寄 存 器 列<br />

表 。 寄 存 器 列 表 指 定 :<br />

• 作 为 输 入 参 数 的 寄 存 器 ;<br />

• 返 回 后 作 为 输 出 参 数 的 寄 存 器 ;<br />

• 被 所 调 用 函 数 破 坏 的 寄 存 器 。<br />

这 些 指 令 的 语 法 是 :<br />

SWI{cond} swi_num, {input_param_list}, {output_value_list}, {corrupt_reg_list}<br />

BL{cond} function, {input_param_list}, {output_value_list}, {corrupt_reg_list}<br />

例 如 :<br />

BL foo {r0=expression1, r1=expression2, r2}, {result=r0, r1}<br />

省 略 的 列 表 将 视 为 空 列 表 , 而 BL 总 是 破 坏 ip 和 lr。BL 的 默 认 破 坏 列 表 是 r0-r3。<br />

5-6 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


混 合 使 用 C、C++ 和 汇 编 语 言<br />

如 果 未 指 定 任 何 列 表 , 则 :<br />

• r0-r3 用 作 输 入 参 数 ;<br />

• r0 用 于 输 出 值 ;<br />

• r12 和 r14 被 破 坏 。<br />

寄 存 器 列 表 的 语 法 与 LDM 和 STM 寄 存 器 列 表 相 同 。 如 果 修 改 了 NZCV 标 志 , 则 必<br />

须 在 破 坏 寄 存 器 列 表 中 指 定 PSR。<br />

5.1.3 内 联 汇 编 程 序 和 armasm 的 不 同 点<br />

内 联 汇 编 程 序 接 受 的 汇 编 语 言 和 <strong>ARM</strong> 汇 编 程 序 接 受 的 汇 编 语 言 之 间 有 大 量 不<br />

同 之 处 和 限 制 。 对 于 内 联 汇 编 程 序 :<br />

• 不 能 用 点 表 示 法 (.) 或 {PC} 获 取 当 前 指 令 的 地 址 。<br />

• 不 支 持 LDR Rn, = 表 达 式 伪 指 令 。 请 使 用 MOV Rn, 表 达 式 代 替 ( 它 可 以 从 文 字<br />

池 装 载 )。<br />

• 不 支 持 标 号 表 达 式 。<br />

• 不 支 持 ADR 和 ADRL 伪 指 令 。<br />

• 不 能 使 用 & 操 作 符 表 示 十 六 进 制 常 数 。 应 使 用 0x 前 缀 来 代 替 。 例 如 :<br />

__asm {AND x, y, 0xF00}<br />

• 用 于 指 定 8 位 常 数 实 际 循 环 的 表 示 法 在 内 联 汇 编 语 言 中 不 能 使 用 。 这 意 味<br />

着 在 使 用 8 位 移 位 常 数 时 , 如 果 更 新 了 NZCV 标 志 ,C 标 志 必 须 视 为 已 破<br />

坏 的 。<br />

• 必 须 小 心 使 用 寄 存 器 ( 如 r0-r3、 ip、 lr) 和 CPSR 中 的 NZCV 标 志 。 如 果<br />

使 用 C 或 C++ 表 达 式 , 这 些 寄 存 器 可 能 被 用 作 临 时 寄 存 器 , 并 且 NZCV<br />

标 志 可 能 在 计 算 表 达 式 时 被 编 译 程 序 破 坏 。 请 参 阅 第 5-5 页 的 虚 拟 和 物 理<br />

寄 存 器 。<br />

• 没 有 为 PC (r15)、lr (r14) 和 sp (r13) 寄 存 器 创 建 虚 拟 寄 存 器 , 而 且 不 能 在 内<br />

联 汇 编 代 码 中 读 取 或 直 接 修 改 它 们 。 有 关 虚 拟 寄 存 器 的 详 细 信 息 , 请 参 阅<br />

第 5-5 页 的 虚 拟 和 物 理 寄 存 器 。<br />

• 您 不 能 写 入 PC。 不 支 持 BX、 BXJ、 BLX 和 BKPT 指 令 。<br />

• 不 得 修 改 栈 。 这 是 没 有 必 要 的 , 因 为 编 译 程 序 根 据 需 要 自 动 将 任 何 工 作 寄<br />

存 器 压 栈 和 恢 复 。 不 允 许 明 确 压 栈 和 恢 复 工 作 寄 存 器 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 5-7


混 合 使 用 C、 C++ 和 汇 编 语 言<br />

5.1.4 用 法<br />

• 可 以 更 改 处 理 器 模 式 、 改 变 ATPCS 寄 存 器 fp、 sl 和 sb, 或 者 改 变 协 处 理<br />

器 状 态 , 但 编 译 程 序 不 会 意 识 到 所 做 的 更 改 。 如 果 更 改 处 理 器 模 式 , 则 直<br />

到 改 回 到 原 模 式 时 才 能 使 用 C 或 C++ 表 达 式 , 因 为 编 译 程 序 将 破 坏 用 于<br />

更 改 后 处 理 器 模 式 的 寄 存 器 。<br />

类 似 地 , 如 果 通 过 执 行 浮 点 指 令 更 改 了 浮 点 协 处 理 器 状 态 , 则 直 到 恢 复 原<br />

状 态 后 , 才 能 使 用 浮 点 表 达 式 。<br />

以 下 几 点 适 用 于 内 联 汇 编 语 言 :<br />

• 在 汇 编 语 言 中 , 逗 号 用 作 分 隔 符 , 因 此 使 用 逗 号 操 作 符 的 C 表 达 式 必 须 包<br />

含 在 括 号 中 以 区 分 它 们 :<br />

__asm {ADD x, y, (f(), z)}<br />

• 在 内 联 汇 编 程 序 中 , 寄 存 器 名 视 为 C 或 C++ 变 量 。 它 们 不 一 定 与 相 同 名<br />

称 的 物 理 寄 存 器 相 关 ( 请 参 阅 第 5-5 页 的 虚 拟 和 物 理 寄 存 器 )。 如 果 未 将<br />

寄 存 器 声 明 为 C 或 C++ 变 量 , 则 编 译 程 序 会 发 出 警 告 , 提 醒 您 将 它 声 明<br />

为 变 量 。<br />

• 在 内 联 汇 编 程 序 中 不 要 保 存 和 恢 复 寄 存 器 。 编 译 程 序 为 您 完 成 此 操 作 。 此<br />

外 , 内 联 汇 编 程 序 不 提 供 对 物 理 寄 存 器 的 直 接 访 问 ( 请 参 阅 第 5-5 页 的 虚<br />

拟 和 物 理 寄 存 器 )。 对 除 CPSR 和 SPSR 之 外 的 寄 存 器 , 如 果 在 读 取 其 之<br />

前 没 有 写 入 , 将 发 出 错 误 信 息 。 例 如 :<br />

int f(int x)<br />

{<br />

__asm<br />

{<br />

STMFD sp!, {r0}<br />

ADD r0, x, 1<br />

EOR x, r0, x<br />

LDMFD sp!, {r0}<br />

}<br />

return x;<br />

}<br />

该 函 数 必 须 写 为 下 列 形 式 :<br />

int f(int x)<br />

{<br />

int r0;<br />

__asm<br />

{<br />

ADD r0, x, 1<br />

// save r0 - illegal: read before write<br />

// restore r0 - not needed.<br />

5-8 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


混 合 使 用 C、C++ 和 汇 编 语 言<br />

}<br />

EOR x, r0, x<br />

}<br />

return x;<br />

5.1.5 示 例<br />

示 例 5-2 和 第 5-10 页 的 示 例 5-3 中 示 范 了 一 些 可 以 有 效 使 用 内 联 汇 编 语 言 的 方 法 。<br />

启 用 和 禁 用 中 断<br />

通 过 读 取 CPSR 标 志 并 更 新 第 7 位 , 可 以 启 用 或 禁 用 中 断 。 示 例 5-2 显 示 如 何 使<br />

用 可 以 内 联 的 小 函 数 完 成 此 操 作 。<br />

在 Examples_directory\inline\irqs.c. 中 也 有 此 代 码 。<br />

这 些 函 数 仅 在 特 权 模 式 下 起 作 用 , 因 为 在 “ 用 户 ” 模 式 下 不 能 更 改 CPSR 和<br />

SPSR 的 控 制 位 。<br />

示 例 5-2 中 断<br />

__inline void enable_IRQ(void)<br />

{<br />

int tmp;<br />

__asm<br />

{<br />

MRS tmp, CPSR<br />

BIC tmp, tmp, #0x80<br />

MSR CPSR_c, tmp<br />

}<br />

}<br />

__inline void disable_IRQ(void)<br />

{<br />

int tmp;<br />

__asm<br />

{<br />

MRS tmp, CPSR<br />

ORR tmp, tmp, #0x80<br />

MSR CPSR_c, tmp<br />

}<br />

}<br />

int main(void)<br />

{<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 5-9


混 合 使 用 C、 C++ 和 汇 编 语 言<br />

}<br />

disable_IRQ();<br />

enable_IRQ();<br />

标 量 积<br />

示 例 5-3 计 算 两 个 整 型 数 组 的 标 量 积 。 它 说 明 对 于 内 联 汇 编 程 序 不 直 接 支 持 的 C<br />

或 C++ 表 达 式 和 数 据 类 型 , 内 联 汇 编 语 言 如 何 与 其 交 互 。 内 联 函 数 mlal() 被 优<br />

化 为 单 个 SMLAL 指 令 。 使 用 -S -fs 编 译 程 序 选 项 可 以 查 看 编 译 程 序 生 成 的 汇 编 语<br />

言 代 码 。<br />

long long 与 __int64 相 同 。<br />

在 Examples_directory\inline\dotprod.c 中 也 有 此 代 码 。<br />

示 例 5-3 标 量 积<br />

#include <br />

/* change word order if big-endian */<br />

#define lo64(a) (((unsigned*) &a)[0]) /* low 32 bits of a long long */<br />

#define hi64(a) (((int*) &a)[1]) /* high 32 bits of a long long */<br />

__inline __int64 mlal(__int64 sum, int a, int b)<br />

{<br />

#if !defined(__thumb) && defined(__TARGET_FEATURE_MULTIPLY)<br />

__asm<br />

{<br />

SMLAL lo64(sum), hi64(sum), a, b<br />

}<br />

#else<br />

sum += (__int64) a * (__int64) b;<br />

#endif<br />

return sum;<br />

}<br />

__int64 dotprod(int *a, int *b, unsigned n)<br />

{<br />

__int64 sum = 0;<br />

do<br />

sum = mlal(sum, *a++, *b++);<br />

while (--n != 0);<br />

return sum;<br />

}<br />

int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };<br />

int b[10] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };<br />

5-10 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


混 合 使 用 C、C++ 和 汇 编 语 言<br />

int main(void)<br />

{<br />

printf("Dotproduct %lld (should be %d)\n", dotprod(a, b, 10), 220);<br />

return 0;<br />

}<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 5-11


混 合 使 用 C、 C++ 和 汇 编 语 言<br />

5.2 使 用 嵌 入 式 汇 编 程 序<br />

<strong>ARM</strong> 编 译 程 序 中 内 建 的 嵌 入 式 汇 编 程 序 使 您 可 以 在 一 个 或 多 个 C 或 C++ 函 数<br />

定 义 中 包 含 外 联 的 汇 编 代 码 。 嵌 入 式 汇 编 程 序 提 供 对 目 标 处 理 器 不 受 限 制 的 低<br />

级 别 访 问 , 利 用 它 可 以 使 用 C 和 C++ 预 处 理 器 命 令 并 易 于 访 问 结 构 成 员 偏 移 。<br />

嵌 入 式 汇 编 程 序 允 许 您 使 用 全 部 <strong>ARM</strong> 汇 编 程 序 指 令 集 , 包 括 汇 编 程 序 命 令 。<br />

嵌 入 式 汇 编 代 码 独 立 于 C 或 C++ 代 码 进 行 汇 编 。 然 后 , 所 生 成 的 编 译 对 象 与 C<br />

或 C++ 源 代 码 编 译 对 象 相 结 合 。<br />

<strong>ARM</strong> 和 Thumb 代 码 都 支 持 嵌 入 式 汇 编 程 序 。 有 关 <strong>ARM</strong> 指 令 集 的 详 细 信 息 , 请<br />

参 阅 <strong>RealView</strong> 编 译 工 具 2.0 版 汇 编 程 序 指 南 。<br />

有 关 嵌 入 式 汇 编 程 序 的 详 细 信 息 , 请 参 阅 <strong>RealView</strong> 编 译 工 具 2.0 版 编 译 程 序 和<br />

库 指 南 中 关 于 内 联 和 嵌 入 式 汇 编 程 序 一 章 。<br />

5.2.1 调 用 嵌 入 式 汇 编 程 序<br />

嵌 入 式 汇 编 函 数 的 定 义 用 __asm 函 数 限 定 符 标 记 出 来 。 用 __asm 声 明 的 函 数 可 以<br />

有 自 变 量 并 返 回 一 个 类 型 。 它 们 从 C 和 C++ 中 调 用 的 方 式 与 普 通 C 和 C++ 函 数<br />

调 用 方 式 相 同 。 嵌 入 式 汇 编 函 数 语 法 是 :<br />

__asm return-type function-name(parameter-list)<br />

{<br />

// <strong>ARM</strong>/Thumb assembler code<br />

}<br />

指 令<br />

...<br />

[instruction]<br />

备 注<br />

自 变 量 名 允 许 用 在 参 数 列 表 中 , 但 不 能 用 在 嵌 入 式 汇 编 函 数 体 内 。 例 如 , 以 下<br />

函 数 在 函 数 体 内 使 用 整 数 i, 但 在 汇 编 中 无 效 :<br />

__asm int f(int i) {<br />

ADD i, i, #1 // error<br />

}<br />

例 如 , 可 以 使 用 r0 代 替 i。<br />

5-12 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


混 合 使 用 C、C++ 和 汇 编 语 言<br />

用 嵌 入 式 汇 编 函 数 实 现 加 法 示 例<br />

示 例 5-4 显 示 使 用 嵌 入 式 汇 编 函 数 将 两 个 值 相 加 的 示 例 。 将 它 与 第 5-4 页 的 示 例<br />

5-1 中 的 内 联 汇 编 代 码 进 行 比 较 。<br />

示 例 5-4 用 嵌 入 式 汇 编 函 数 实 现 加 法<br />

#include <br />

__asm int add(int i, int j) {<br />

ADD r0,r0,r1 // Value of i in r0 and j in r1, result in r0<br />

MOV pc,lr<br />

}<br />

void main() {<br />

printf("12345 + 67890 = %d\n", add(12345, 67890));<br />

}<br />

5.2.2 嵌 入 式 汇 编 语 句 的 限 制<br />

以 下 约 束 适 用 于 嵌 入 式 汇 编 函 数 :<br />

• 预 处 理 后 , __asm 函 数 只 能 包 含 汇 编 代 码 , 以 下 标 识 符 除 外 :<br />

__cpp(expr)<br />

__offsetof_base(D, B)<br />

__mcall_is_virtual(D, f)<br />

__mcall_is_in_vbase(D, f)<br />

__mcall_this_offset(D, f)<br />

__vcall_offsetof_vfunc(D, f)<br />

• 编 译 程 序 不 为 __asm 函 数 生 成 返 回 指 令 。 如 果 要 从 __asm 函 数 返 回 , 必 须 将<br />

用 汇 编 代 码 编 写 的 返 回 指 令 包 含 到 函 数 体 内 。<br />

备 注<br />

因 为 嵌 入 式 汇 编 程 序 保 证 按 照 已 定 义 的 顺 序 发 出 __asm 函 数 , 所 以 这 使 得<br />

转 到 下 一 个 函 数 成 为 可 能 。 然 而 , 内 联 和 模 板 函 数 的 表 现 有 所 不 同 。<br />

• __asm 函 数 不 更 改 应 用 的 ATPCS 规 则 。 这 意 味 着 , 即 使 __asm 函 数 可 用 的<br />

汇 编 代 码 ( 例 如 , 更 改 状 态 ) 中 没 有 限 制 , 在 __asm 函 数 和 普 通 C 或 C++<br />

函 数 之 间 的 所 有 调 用 也 必 须 紧 随 ATPCS。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 5-13


混 合 使 用 C、 C++ 和 汇 编 语 言<br />

有 关 详 细 信 息 , 请 参 阅 <strong>RealView</strong> 编 译 工 具 2.0 版 编 译 程 序 和 库 指 南 中 关 于 内 联<br />

和 嵌 入 式 汇 编 程 序 一 章 。<br />

5.2.3 嵌 入 式 汇 编 程 序 和 C 或 C++ 的 不 同 点<br />

要 清 楚 嵌 入 式 汇 编 程 序 表 达 式 和 C 或 C++ 表 达 式 之 间 的 以 下 差 异 :<br />

• 汇 编 程 序 表 达 式 总 是 无 符 号 的 。 相 同 的 表 达 式 在 汇 编 程 序 和 C 或 C++ 中<br />

有 不 同 值 。 例 如 :<br />

MOV r0, #(-33554432 / 2)<br />

MOV r0, #__cpp(-33554432 / 2)<br />

// result is 0x7f000000<br />

// result is 0xff000000<br />

• 含 有 前 导 零 的 汇 编 程 序 编 号 仍 是 十 进 制 的 。 例 如 :<br />

MOV r0, #0700 // decimal 700<br />

MOV r0, #__cpp(0700) // octal 0700 == decimal 448<br />

• 汇 编 程 序 运 算 符 优 先 顺 序 与 C 和 C++ 不 同 。 例 如 :<br />

MOV r0, #(0x23 :AND: 0xf + 1) // ((0x23 & 0xf) + 1) => 4<br />

MOV r0, #__cpp(0x23 & 0xf + 1) // (0x23 & (0xf + 1)) => 0<br />

• 汇 编 程 序 字 符 串 不 是 空 终 止 的 :<br />

DCB "no trailing null"<br />

DCB __cpp("I have a trailing null!!")<br />

// 16 bytes<br />

// 25 bytes<br />

备 注<br />

汇 编 程 序 规 则 应 用 于 __cpp 之 外 , 而 C 或 C++ 规 则 应 用 于 __cpp 之 内 。 有 关<br />

__cpp 关 键 字 的 详 细 信 息 , 请 参 阅 <strong>RealView</strong> 编 译 工 具 2.0 版 编 译 程 序 和 库 指 南 中<br />

关 于 内 联 和 嵌 入 式 汇 编 程 序 一 章 。<br />

5-14 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


混 合 使 用 C、C++ 和 汇 编 语 言<br />

5.3 内 联 汇 编 代 码 与 嵌 入 式 汇 编 代 码 之 间 的 差 异<br />

内 联 和 嵌 入 式 汇 编 的 编 译 方 法 有 所 不 同 :<br />

• 内 联 汇 编 代 码 使 用 高 级 处 理 器 分 离 , 并 在 代 码 生 成 过 程 中 与 C 和 C++ 代<br />

码 集 成 。 因 此 , 编 译 程 序 将 C 和 C++ 代 码 与 汇 编 代 码 一 起 进 行 优 化 。<br />

• 与 内 联 汇 编 代 码 不 同 , 嵌 入 式 汇 编 代 码 从 C 和 C++ 代 码 中 分 离 出 来 单 独<br />

进 行 汇 编 , 产 生 与 C 和 C++ 源 代 码 编 译 对 象 相 结 合 的 编 译 对 象 。<br />

• 可 通 过 编 译 程 序 来 内 联 内 联 汇 编 代 码 , 但 无 论 是 显 式 还 是 隐 式 , 都 无 法 内<br />

联 嵌 入 式 汇 编 代 码 。<br />

表 5-1 汇 总 了 内 联 汇 编 程 序 与 嵌 入 式 汇 编 程 序 之 间 的 主 要 差 异 。<br />

表 5-1 内 联 汇 编 程 序 与 嵌 入 式 汇 编 程 序 之 间 的 差 异<br />

功 能 嵌 入 式 汇 编 程 序 内 联 汇 编 程 序<br />

指 令 集 <strong>ARM</strong> 和 Thumb 仅 限 <strong>ARM</strong><br />

<strong>ARM</strong> 汇 编 程 序 命 令 全 部 支 持 不 支 持<br />

C/C++ 表 达 式 仅 限 常 量 表 达 式 完 整 C/C++ 表 达 式<br />

优 化 汇 编 代 码 不 优 化 全 部 优 化<br />

内 联 否 可 能<br />

寄 存 器 访 问<br />

返 回 指 令<br />

使 用 指 定 的 物 理 寄 存<br />

器 。 还 可 以 使 用 PC、<br />

LR 和 SP。<br />

必 须 将 其 添 加 到 代<br />

码 中 。<br />

使 用 虚 拟 寄 存 器 ( 参 阅<br />

第 5-5 页 的 虚 拟 和 物 理<br />

寄 存 器 )<br />

自 动 生 成<br />

备 注<br />

嵌 入 式 汇 编 程 序 和 C 或 C++ 之 间 的 差 异 列 表 位 于 第 5-14 页 的 嵌 入 式 汇 编 程 序<br />

和 C 或 C++ 的 不 同 点 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 5-15


混 合 使 用 C、 C++ 和 汇 编 语 言<br />

5.4 从 汇 编 代 码 访 问 C 全 局 变 量<br />

只 能 通 过 地 址 间 接 访 问 全 局 变 量 。 要 访 问 全 局 变 量 , 请 使 用 IMPORT 命 令 输 入 全<br />

局 变 量 , 然 后 将 地 址 载 入 寄 存 器 。 可 以 根 据 变 量 的 类 型 使 用 载 入 和 存 储 指 令 访<br />

问 该 变 量 。<br />

对 于 无 符 号 变 量 , 使 用 :<br />

• LDRB/STRB 用 于 char 型 ;<br />

• LDRH/STRH 用 于 short 型 ( 对 于 <strong>ARM</strong> 体 系 结 构 v3, 使 用 两 个 LDRB/STRB<br />

指 令 );<br />

• LDR/STR 用 于 int 型 。<br />

对 于 有 符 号 变 量 , 请 使 用 等 效 的 有 符 号 指 令 , 如 LDRSB 和 LDRSH。<br />

可 以 用 LDM 和 STM 指 令 作 为 整 体 访 问 少 于 8 个 字 的 小 结 构 。 可 以 用 适 当 类 型 的 载<br />

入 和 存 储 指 令 访 问 结 构 的 单 个 成 员 。 为 了 访 问 成 员 , 必 须 了 解 该 成 员 从 结 构 开<br />

始 处 的 偏 移 量 。<br />

示 例 5-5 将 整 型 全 局 变 量 globvar 的 地 址 载 入 r1、 将 该 地 址 中 包 含 的 值 载 入 r0、<br />

将 它 与 2 相 加 , 然 后 将 新 值 存 回 globvar 中 。<br />

示 例 5-5 全 局 地 址<br />

AREA<br />

EXPORT<br />

IMPORT<br />

globals,CODE,READONLY<br />

asmsubroutine<br />

globvar<br />

asmsubroutine<br />

LDR r1, =globvar<br />

LDR r0, [r1]<br />

ADD r0, r0, #2<br />

STR r0,[r1]<br />

MOV pc, lr<br />

END<br />

; read address of globvar into<br />

; r1 from literal pool<br />

5-16 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


混 合 使 用 C、C++ 和 汇 编 语 言<br />

5.5 在 C++ 中 使 用 C 头 文 件<br />

本 节 描 述 如 何 在 C++ 代 码 中 使 用 C 头 文 件 。 从 C++ 调 用 C 头 文 件 之 前 ,C 头 文<br />

件 必 须 包 含 在 extern "C" 命 令 中 。<br />

5.5.1 包 括 系 统 C 头 文 件<br />

要 包 括 标 准 的 系 统 C 头 文 件 , 如 stdio.h, 不 必 进 行 特 殊 操 作 。 标 准 C 头 文 件 已<br />

经 包 含 适 当 的 extern "C" 命 令 。 例 如 :<br />

#include <br />

int main()<br />

{<br />

... // C++ code<br />

return 0;<br />

}<br />

如 果 使 用 此 语 法 包 含 头 文 件 , 则 所 有 库 名 都 放 在 全 局 命 名 空 间 中 。<br />

C++ 标 准 指 定 可 通 过 特 定 的 C++ 头 文 件 获 取 C 头 文 件 的 功 能 。 这 些 文 件 与 标 准<br />

C 头 文 件 一 起 安 装 在 install_directory\RVCT\Data\2.0\build_num\platform\include 中 ,<br />

可 以 用 常 规 方 法 进 行 引 用 。 例 如 :<br />

#include <br />

int main()<br />

{<br />

... // C++ code<br />

return 0;<br />

}<br />

在 <strong>ARM</strong> C++ 中 , 这 些 头 文 件 中 包 含 (#include) C 头 文 件 。 如 果 使 用 此 语 法 包 含<br />

头 文 件 , 则 所 有 C++ 标 准 库 名 都 在 命 名 空 间 std 中 定 义 , 包 括 C 库 名 。 这 意 味<br />

着 必 须 使 用 下 列 方 法 之 一 来 限 定 所 有 的 库 名 称 。<br />

• 指 定 标 准 命 名 空 间 , 例 如 :<br />

std::printf("example\n");<br />

• 使 用 C++ 关 键 字 using 向 全 局 命 名 空 间 输 入 一 个 名 称 :<br />

using namespace std;<br />

printf("example\n");<br />

• 使 用 编 译 程 序 选 项 --using_std。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 5-17


混 合 使 用 C、 C++ 和 汇 编 语 言<br />

5.5.2 包 含 您 自 己 的 C 头 文 件<br />

要 包 含 自 己 的 C 头 文 件 , 您 必 须 将 #include 命 令 包 在 extern "C" 语 句 中 。 可 以 用<br />

以 下 方 法 完 成 此 操 作 :<br />

• 当 文 件 已 经 被 包 含 (#include) 时 。 如 示 例 5-6 所 示 。<br />

• 将 extern "C" 语 句 添 加 到 头 文 件 。 如 示 例 5-7 所 示 。<br />

示 例 5-6 包 含 文 件 之 前 使 用 命 令<br />

// C++ code<br />

extern "C" {<br />

#include "my-header1.h"<br />

#include "my-header2.h"<br />

}<br />

int main()<br />

{<br />

// ...<br />

return 0;<br />

}<br />

示 例 5-7 头 文 件 中 使 用 命 令<br />

/* C header file */<br />

#ifdef __cplusplus /* Insert start of extern C construct */<br />

extern "C" {<br />

#endif<br />

/* Body of header file */<br />

#ifdef __cplusplus /* Insert end of extern C construct */<br />

} /* The C header file can now be */<br />

#endif /* included in either C or C++ code. */<br />

5-18 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


混 合 使 用 C、C++ 和 汇 编 语 言<br />

5.6 C、 C++ 和 <strong>ARM</strong> 汇 编 语 言 之 间 的 调 用<br />

本 节 提 供 一 些 示 例 , 帮 助 您 从 C++ 调 用 C 和 汇 编 语 言 代 码 , 以 及 从 C 和 汇 编 语<br />

言 调 用 C++ 代 码 。 还 描 述 了 调 用 约 定 和 数 据 类 型 。<br />

只 要 遵 循 正 确 的 过 程 ATPCS 调 用 标 准 , 就 可 以 混 合 调 用 C、 C++ 和 汇 编 语 言 例<br />

程 。 有 关 ATPCS 的 更 多 信 息 , 请 参 阅 第 3 章 使 用 过 程 调 用 标 准 。<br />

备 注<br />

本 节 中 的 信 息 与 具 体 的 实 现 情 况 相 关 , 可 能 在 将 来 版 本 的 工 具 箱 中 会 有 所 改 变 。<br />

5.6.1 语 言 交 叉 调 用 的 一 般 规 则<br />

以 下 一 般 规 则 适 用 于 C、 C++ 和 汇 编 语 言 之 间 的 调 用 。 有 关 的 详 细 信 息 , 请 参<br />

阅 <strong>RealView</strong> 编 译 工 具 2.0 版 编 译 程 序 和 库 指 南 。<br />

嵌 入 式 汇 编 程 序 以 及 与 <strong>ARM</strong> 嵌 入 式 应 用 程 序 二 进 制 接 口 (EABI) 的 兼 容 使 得 混<br />

合 语 言 编 程 更 易 于 实 现 。 它 们 可 提 供 以 下 帮 助 :<br />

• 使 用 __cpp 关 键 字 进 行 名 称 延 伸 ;<br />

• 传 递 隐 含 this 参 数 的 方 式 ;<br />

• 调 用 虚 函 数 的 方 式 ;<br />

• 引 用 的 表 示 ;<br />

• 具 有 基 类 或 虚 成 员 函 数 的 C++ 类 的 类 型 布 局 ;<br />

• 非 plain old data (POD) 结 构 的 类 对 象 传 递 。<br />

以 下 一 般 规 则 适 用 于 混 合 语 言 编 程 :<br />

• 使 用 C 调 用 约 定 。<br />

• 在 C++ 中 , 非 成 员 函 数 可 以 声 明 为 extern "C", 以 指 定 它 们 有 C 链 接 。 在<br />

此 版 本 RVCT 中 , 带 有 C 链 接 意 味 着 定 义 函 数 的 符 号 未 延 伸 。C 链 接 可 以<br />

用 于 以 一 种 语 言 实 现 函 数 , 然 后 用 另 一 种 语 言 调 用 它 。<br />

备 注<br />

不 能 超 载 用 extern "C" 声 明 的 函 数 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 5-19


混 合 使 用 C、 C++ 和 汇 编 语 言<br />

• 汇 编 语 言 模 块 所 必 须 符 合 的 ATPCS 调 用 标 准 , 应 当 适 合 于 应 用 程 序 所 使<br />

用 的 存 储 器 模 型 。<br />

以 下 规 则 适 用 于 从 C 和 汇 编 语 言 调 用 C++ 函 数 :<br />

• 要 调 用 全 局 ( 非 成 员 ) C++ 函 数 , 应 将 它 声 明 为 extern "C", 以 提 供 C<br />

链 接 。<br />

• 成 员 函 数 ( 静 态 和 非 静 态 ) 总 是 有 已 延 伸 的 名 称 。 使 用 嵌 入 式 汇 编 程 序 的<br />

__cpp 关 键 字 , 您 可 以 不 必 手 工 寻 找 已 延 伸 的 名 称 。<br />

• 不 能 从 C 调 用 C++ 内 联 函 数 , 除 非 确 保 C++ 编 译 程 序 生 成 了 函 数 的 外 联<br />

副 本 。 例 如 , 取 得 函 数 地 址 将 导 致 生 成 外 联 副 本 。<br />

• 非 静 态 成 员 函 数 接 受 隐 含 this 参 数 作 为 r0 中 的 第 一 个 自 变 量 , 或 作 为 r1<br />

中 第 二 个 自 变 量 ( 如 果 函 数 返 回 非 int 类 结 构 )。 静 态 成 员 函 数 不 接 受 隐<br />

含 this 参 数 。<br />

5.6.2 C++ 的 特 定 信 息<br />

以 下 内 容 专 门 适 用 于 C++。<br />

C++ 调 用 约 定<br />

<strong>ARM</strong> C++ 使 用 与 <strong>ARM</strong> C 相 同 的 调 用 约 定 , 但 有 以 下 异 常 :<br />

• 调 用 非 静 态 成 员 函 数 时 , 隐 含 的 this 参 数 是 第 一 个 自 变 量 , 或 者 是 第 二 个<br />

自 变 量 ( 如 果 被 调 用 函 数 返 回 非 int 类 的 struct)。 这 可 能 在 将 来 实 现 时<br />

有 所 变 化 。<br />

C++ 数 据 类 型<br />

<strong>ARM</strong> C++ 使 用 与 <strong>ARM</strong> C 相 同 的 数 据 类 型 , 但 有 以 下 异 常 :<br />

• 如 果 struct 或 class 类 型 的 C++ 对 象 没 有 基 类 或 虚 函 数 , 则 它 们 的 布 局 与<br />

<strong>ARM</strong> C 相 同 。 如 果 这 样 的 struct 没 有 用 户 定 义 的 复 制 赋 值 运 算 符 或 用 户<br />

定 义 的 析 构 函 数 , 则 它 是 POD 结 构 。<br />

• 引 用 表 示 为 指 针 。<br />

• C 函 数 指 针 和 C++ ( 非 成 员 ) 函 数 指 针 没 有 区 别 。<br />

5-20 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


混 合 使 用 C、C++ 和 汇 编 语 言<br />

符 号 名 称 延 伸<br />

链 接 程 序 将 取 消 信 息 中 符 号 名 称 的 延 伸 。<br />

在 C++ 程 序 中 , C 名 称 必 须 声 明 为 extern "C"。 已 经 为 <strong>ARM</strong> ISO C 头 文 件 完 成<br />

此 操 作 。 有 关 详 细 信 息 请 参 阅 第 5-17 页 的 在 C++ 中 使 用 C 头 文 件 。<br />

5.6.3 示 例<br />

下 列 章 节 中 包 含 有 代 码 示 例 , 说 明 :<br />

• 从 C 调 用 汇 编 语 言 ;<br />

• 第 5-23 页 的 从 汇 编 语 言 调 用 C ;<br />

• 第 5-23 页 的 从 C++ 调 用 C ;<br />

• 第 5-24 页 的 从 C++ 调 用 汇 编 语 言 ;<br />

• 第 5-25 页 的 从 C 调 用 C++ ;<br />

• 第 5-26 页 的 从 汇 编 语 言 调 用 C++ ;<br />

• 第 5-28 页 的 从 C 或 汇 编 语 言 调 用 C++ ;<br />

• 第 5-27 页 的 在 C 和 C++ 之 间 传 递 引 用 。<br />

这 些 示 例 假 设 默 认 为 使 用 非 软 件 栈 检 查 的 ATPCS 变 体 , 因 为 它 们 执 行 栈 操 作 时<br />

不 检 查 栈 溢 出 。<br />

从 C 调 用 汇 编 语 言<br />

示 例 5-8 和 第 5-22 页 的 示 例 5-9 显 示 的 C 程 序 调 用 了 汇 编 语 言 子 程 序 , 其 中 将<br />

一 个 字 符 串 复 制 到 另 一 个 字 符 串 中 。<br />

示 例 5-8 从 C 调 用 汇 编 语 言<br />

#include <br />

extern void strcopy(char *d, const char *s);<br />

int main()<br />

{ const char *srcstr = "First string - source ";<br />

char dststr[] = "Second string - destination ";<br />

/* dststr is an array since we 抮 e going to change it */<br />

printf("Before copying:\n");<br />

printf(" %s\n %s\n",srcstr,dststr);<br />

strcopy(dststr,srcstr);<br />

printf("After copying:\n");<br />

printf(" %s\n %s\n",srcstr,dststr);<br />

return (0);<br />

}<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 5-21


混 合 使 用 C、 C++ 和 汇 编 语 言<br />

示 例 5-9 汇 编 语 言 字 符 串 复 制 子 程 序<br />

AREA SCopy, CODE, READONLY<br />

EXPORT strcopy<br />

strcopy<br />

; r0 points to destination string.<br />

; r1 points to source string.<br />

LDRB r2, [r1],#1 ; Load byte and update address.<br />

STRB r2, [r0],#1 ; Store byte and update address.<br />

CMP r2, #0 ; Check for zero terminator.<br />

BNE strcopy ; Keep going if not.<br />

MOV pc,lr<br />

; Return.<br />

END<br />

第 5-21 页 的 示 例 5-8 位 于 Examples_directory\asm 中 , 文 件 名 为 strtest.c 和<br />

scopy.s。 按 以 下 步 骤 从 命 令 行 编 译 该 示 例 :<br />

1. 键 入 armasm -g scopy.s 编 译 汇 编 语 言 源 代 码 。<br />

2. 键 入 armcc -c -g strtest.c 编 译 C 源 代 码 。<br />

3. 键 入 armlink strtest.o scopy.o -o strtest 链 接 目 标 文 件 。<br />

4. 将 ELF/DWARF2 兼 容 调 试 器 与 相 应 调 试 目 标 配 合 使 用 , 运 行 映 象 。<br />

5-22 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


混 合 使 用 C、C++ 和 汇 编 语 言<br />

从 汇 编 语 言 调 用 C<br />

示 例 5-10 和 示 例 5-11 显 示 如 何 从 汇 编 语 言 调 用 C。<br />

示 例 5-10 定 义 C 语 言 函 数<br />

int g(int a, int b, int c, int d, int e)<br />

{<br />

return a + b + c + d + e;<br />

}<br />

示 例 5-11 汇 编 语 言 调 用<br />

; int f(int i) { return g(i, 2*i, 3*i, 4*i, 5*i); }<br />

EXPORT f<br />

AREA f, CODE, READONLY<br />

IMPORT g<br />

; i is in r0<br />

STR lr, [sp, #-4]! ; preserve lr<br />

ADD r1, r0, r0 ; compute 2*i (2nd param)<br />

ADD r2, r1, r0 ; compute 3*i (3rd param)<br />

ADD r3, r1, r2 ; compute 5*i<br />

STR r3, [sp, #-4]! ; 5th param on stack<br />

ADD r3, r1, r1 ; compute 4*i (4th param)<br />

BL g<br />

; branch to C function<br />

ADD sp, sp, #4 ; remove 5th param<br />

LDR pc, [sp], #4 ; return<br />

END<br />

从 C++ 调 用 C<br />

示 例 5-12 和 第 5-24 页 的 示 例 5-13 显 示 如 何 从 C++ 调 用 C。<br />

示 例 5-12 从 C++ 调 用 C 函 数<br />

struct S {<br />

// has no base classes<br />

// or virtual functions<br />

S(int s) : i(s) { }<br />

int i;<br />

};<br />

extern "C" void cfunc(S *);<br />

// declare the C function to be called from C++<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 5-23


混 合 使 用 C、 C++ 和 汇 编 语 言<br />

int f(){<br />

S s(2);<br />

cfunc(&s);<br />

return s.i * 3;<br />

}<br />

// initialize 's'<br />

// call 'cfunc' so it can change 's'<br />

示 例 5-13 定 义 C 语 言 函 数<br />

struct S {<br />

int i;<br />

};<br />

void cfunc(struct S *p) {<br />

/* the definition of the C function to be called from C++ */<br />

p->i += 5;<br />

}<br />

从 C++ 调 用 汇 编 语 言<br />

示 例 5-14 和 第 5-25 页 的 示 例 5-15 显 示 如 何 从 C++ 调 用 汇 编 语 言 。<br />

示 例 5-14 从 C++ 调 用 汇 编 语 言<br />

struct S { // has no base classes<br />

// or virtual functions<br />

S(int s) : i(s) { }<br />

int i;<br />

};<br />

extern "C" void asmfunc(S *);<br />

int f() {<br />

S s(2);<br />

asmfunc(&s);<br />

return s.i * 3;<br />

}<br />

// declare the Asm function<br />

// to be called<br />

// initialize 's'<br />

// call 'asmfunc' so it<br />

// can change 's'<br />

5-24 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


混 合 使 用 C、C++ 和 汇 编 语 言<br />

示 例 5-15 定 义 汇 编 语 言 函 数<br />

AREA Asm, CODE<br />

EXPORT asmfunc<br />

asmfunc<br />

LDR r1, [r0]<br />

ADD r1, r1, #5<br />

STR r1, [r0]<br />

MOV pc, lr<br />

END<br />

; the definition of the Asm<br />

; function to be called from C++<br />

从 C 调 用 C++<br />

示 例 5-16 和 示 例 5-17 显 示 如 何 从 C 调 用 C++。<br />

示 例 5-16 定 义 被 调 用 的 C++ 函 数<br />

struct S { // has no base classes or virtual functions<br />

S(int s) : i(s) { }<br />

int i;<br />

};<br />

extern "C" void cppfunc(S *p) {<br />

// Definition of the C++ function to be called from C.<br />

// The function is written in C++, only the linkage is C<br />

p->i += 5; //<br />

}<br />

示 例 5-17 在 C 中 声 明 并 调 用 该 函 数<br />

struct S {<br />

int i;<br />

};<br />

extern void cppfunc(struct S *p);<br />

/* Declaration of the C++ function to be called from C */<br />

int f(void) {<br />

struct S s;<br />

s.i = 2; /* initialize 's' */<br />

cppfunc(&s); /* call 'cppfunc' so it */<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 5-25


混 合 使 用 C、 C++ 和 汇 编 语 言<br />

}<br />

return s.i * 3;<br />

/* can change 's' */<br />

从 汇 编 语 言 调 用 C++<br />

示 例 5-18 和 示 例 5-19 显 示 如 何 从 汇 编 语 言 调 用 C++。<br />

示 例 5-18 定 义 被 调 用 的 C++ 函 数<br />

struct S {<br />

// has no base classes or virtual functions<br />

S(int s) : i(s) { }<br />

int i;<br />

};<br />

extern "C" void cppfunc(S * p) {<br />

// Definition of the C++ function to be called from ASM.<br />

// The body is C++, only the linkage is C<br />

p->i += 5;<br />

}<br />

在 <strong>ARM</strong> 汇 编 语 言 中 , 输 入 C++ 函 数 名 并 使 用 带 有 链 接 指 令 的 “ 跳 转 ” 调 用 它 :<br />

示 例 5-19 定 义 汇 编 语 言 函 数<br />

AREA Asm, CODE<br />

IMPORT cppfunc<br />

; import the name of the C++<br />

; function to be called from Asm<br />

f<br />

EXPORT<br />

f<br />

STMFD sp!,{lr}<br />

MOV r0,#2<br />

STR r0,[sp,#-4]! ; initialize struct<br />

MOV r0,sp ; argument is pointer to struct<br />

BL cppfunc ; call 'cppfunc' so it can change<br />

; the struct<br />

LDR r0, [sp], #4<br />

ADD r0, r0, r0,LSL #1<br />

LDMFD sp!,{pc}<br />

END<br />

5-26 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


混 合 使 用 C、C++ 和 汇 编 语 言<br />

在 C 和 C++ 之 间 传 递 引 用<br />

示 例 5-20 和 示 例 5-21 显 示 如 何 在 C 和 C++ 之 间 传 递 引 用 。<br />

示 例 5-20 C++ 函 数<br />

extern "C" int cfunc(const int&);<br />

// Declaration of the C function to be called from C++<br />

extern "C" int cppfunc(const int& r) {<br />

// Definition of the C++ to be called from C.<br />

return 7 * r;<br />

}<br />

int f() {<br />

int i = 3;<br />

return cfunc(i);<br />

}<br />

// passes a pointer to 'i'<br />

示 例 5-21 定 义 C 函 数<br />

extern int cppfunc(const int*);<br />

/* declaration of the C++ to be called from C */<br />

int cfunc(const int* p) {<br />

/* definition of the C function to be called from C++ */<br />

int k = *p + 4;<br />

return cppfunc(&k);<br />

}<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 5-27


混 合 使 用 C、 C++ 和 汇 编 语 言<br />

从 C 或 汇 编 语 言 调 用 C++<br />

示 例 5-22、 示 例 5-23 和 第 5-29 页 的 示 例 5-24 中 的 代 码 说 明 如 何 从 C 或 汇 编 语<br />

言 调 用 非 静 态 、 非 虚 的 C++ 成 员 函 数 。 可 以 使 用 编 译 程 序 的 汇 编 程 序 输 出 来 查<br />

找 已 延 伸 的 函 数 名 。<br />

示 例 5-22 调 用 C++ 成 员 函 数<br />

struct T {<br />

T(int i) : t(i) { }<br />

int t;<br />

int f(int i);<br />

};<br />

int T::f(int i) { return i + t; }<br />

// Definition of the C++ function to be called from C.<br />

extern "C" int cfunc(T*);<br />

// declaration of the C function to be called from C++<br />

int f() {<br />

T t(5);<br />

return cfunc(&t);<br />

}<br />

// create an object of type T<br />

示 例 5-23 定 义 C 函 数<br />

struct T;<br />

extern int _ZN1T1fEi(struct T*, int);<br />

/* the mangled name of the C++ */<br />

/* function to be called */<br />

int cfunc(struct T* t) {<br />

/* Definition of the C function to be called from C++. */<br />

return 3 * _ZN1T1fEi(t, 2); /* like '3 * t->f(2)' */<br />

}<br />

5-28 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


混 合 使 用 C、C++ 和 汇 编 语 言<br />

示 例 5-24 在 汇 编 语 言 中 执 行 该 函 数<br />

EXPORT cfunc<br />

AREA cfunc, CODE<br />

IMPORT _ZN1T1fEi<br />

STMFD sp!,{lr} ; r0 already contains the object pointer<br />

MOV r1, #2<br />

BL _ZN1T1fEi<br />

ADD r0, r0, r0, LSL #1 ; multiply by 3<br />

LDMFD sp!,{pc}<br />

END<br />

也 可 以 使 用 嵌 入 式 汇 编 实 现 第 5-28 页 的 示 例 5-22 和 示 例 5-24, 如 示 例 5-25 中<br />

所 示 。 在 此 例 中 , 使 用 __cpp 关 键 字 引 用 该 函 数 。 因 此 , 您 不 必 了 解 已 延 伸 的 函<br />

数 名 。<br />

示 例 5-25 在 嵌 入 式 汇 编 中 执 行 该 函 数<br />

struct T {<br />

T(int i) : t(i) { }<br />

int t;<br />

int f(int i);<br />

};<br />

int T::f(int i) { return i + t; }<br />

// Definition of asm function called from C++<br />

__asm int asm_func(T*) {<br />

STMFD sp!, {lr}<br />

MOV r1, #2;<br />

BL __cpp(T::f);<br />

ADD r0, r0, r0, LSL #1 ; multiply by 3<br />

LDMFD sp!, {pc}<br />

}<br />

int f() {<br />

T t(5); // create an object of type T<br />

return asm_func(&t);<br />

}<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 5-29


混 合 使 用 C、 C++ 和 汇 编 语 言<br />

5-30 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


第 6 章<br />

处 理 处 理 器 异 常<br />

本 章 介 绍 了 如 何 处 理 <strong>ARM</strong> 处 理 器 支 持 的 各 种 类 型 的 异 常 。 其 中 包 含 下 列 各<br />

部 分 :<br />

• 第 6-2 页 的 关 于 处 理 器 异 常 ;<br />

• 第 6-7 页 的 进 入 和 离 开 异 常 ;<br />

• 第 6-13 页 的 安 装 异 常 处 理 程 序 ;<br />

• 第 6-18 页 的 SWI 处 理 程 序 ;<br />

• 第 6-27 页 的 中 断 处 理 程 序 ;<br />

• 第 6-36 页 的 复 位 处 理 程 序 ;<br />

• 第 6-37 页 的 未 定 义 的 指 令 处 理 程 序 ;<br />

• 第 6-38 页 的 预 取 中 断 处 理 程 序 ;<br />

• 第 6-39 页 的 数 据 中 断 处 理 程 序 ;<br />

• 第 6-41 页 的 链 结 异 常 处 理 程 序 ;<br />

• 第 6-43 页 的 系 统 模 式 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 6-1


处 理 处 理 器 异 常<br />

6.1 关 于 处 理 器 异 常<br />

程 序 正 常 执 行 流 程 中 , 程 序 计 数 器 在 其 地 址 范 围 内 连 续 增 加 , 还 可 以 跳 转 至 附 近<br />

程 序 标 号 或 跳 转 并 链 接 到 子 例 程 。<br />

当 该 常 规 执 行 流 程 被 转 向 到 启 用 处 理 器 处 理 内 部 或 外 部 资 源 产 生 的 事 件 时 , 即<br />

发 生 了 处 理 器 异 常 。 此 类 事 件 的 示 例 有 :<br />

• 外 部 产 生 的 中 断 ;<br />

• 处 理 器 试 图 执 行 一 个 未 定 义 的 指 令 ;<br />

• 访 问 有 特 权 的 操 作 系 统 函 数 。<br />

处 理 此 类 异 常 时 , 有 必 要 保 护 处 理 器 先 前 的 状 态 , 以 保 证 在 完 成 相 应 的 异 常 处 理<br />

例 程 后 能 够 恢 复 产 生 异 常 时 程 序 运 行 的 状 态 , 使 其 继 续 执 行 。<br />

表 6-1 展 示 了 <strong>ARM</strong> 处 理 器 识 别 的 不 同 类 型 的 异 常 。<br />

表 6-1 异 常 类 型<br />

异 常<br />

复 位<br />

说 明<br />

在 处 理 器 复 位 管 脚 有 效 时 发 生 。 该 异 常 仅 在 处 理 器 上 电 时 、 或 上 电 后 的 复 位 时 才 发<br />

生 。 可 通 过 跳 转 到 复 位 向 量 (0x0000) 来 完 成 软 复 位 。<br />

未 定 义 指 令 在 处 理 器 或 任 何 协 处 理 器 均 不 能 识 别 当 前 执 行 指 令 时 发 生 。<br />

软 件 中 断 (SWI)<br />

这 是 一 个 用 户 定 义 的 同 步 中 断 指 令 。 它 使 得 在 User 模 式 下 运 行 的 程 序 能 够 请 求 在<br />

Supervisor 模 式 下 运 行 的 特 权 操 作 , 如 RTOS 函 数 。<br />

预 取 中 断 在 处 理 器 试 图 执 行 一 个 未 取 指 令 时 发 生 , 因 为 地 址 非 法 a 。<br />

数 据 中 断 在 数 据 传 送 指 令 试 图 在 非 法 地 址 a 载 入 或 存 储 数 据 时 发 生 。<br />

IRQ 在 处 理 器 外 部 中 断 申 请 管 脚 有 效 ( 低 电 平 ) 且 CPSR 中 的 I 位 为 清 除 时 发 生 。<br />

FIQ 在 处 理 器 外 部 中 断 申 请 管 脚 有 效 ( 低 电 平 ) 且 CPSR 中 的 F 位 为 清 除 时 发 生 。<br />

a. 非 法 虚 拟 地 址 是 与 当 前 物 理 存 储 器 地 址 不 符 的 地 址 , 或 者 是 存 储 器 管 理 子 系 统 决 定 在 当 前 模 式 下 处 理 器 不 可 读 取 的<br />

地 址 。<br />

6-2 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


处 理 处 理 器 异 常<br />

6.1.1 向 量 表<br />

处 理 器 异 常 的 处 理 由 一 个 向 量 表 控 制 。 向 量 表 为 一 个 32 字 节 的 保 留 区 , 通 常<br />

在 存 储 器 映 射 的 底 部 。 它 为 每 一 类 型 的 异 常 分 配 了 一 个 字 的 空 间 , 当 前 有 一 个<br />

保 留 字 。<br />

这 不 是 包 含 处 理 程 序 全 部 代 码 所 需 的 足 够 空 间 , 因 此 在 每 个 异 常 类 型 的 向 量 入<br />

口 通 常 包 含 一 个 跳 转 指 令 或 载 入 PC 指 令 来 继 续 执 行 相 应 的 处 理 程 序 。<br />

6.1.2 异 常 使 用 的 模 式 和 寄 存 器<br />

通 常 , 应 用 程 序 运 行 在 用 户 模 式 下 , 但 是 , 为 异 常 提 供 服 务 需 要 有 特 权 的 ( 即<br />

非 “ 用 户 ” 模 式 ) 操 作 。 异 常 改 变 了 处 理 器 模 式 , 这 反 过 来 意 味 着 每 个 异 常 处<br />

理 程 序 可 以 访 问 编 组 寄 存 器 的 某 些 子 集 :<br />

• 其 自 身 的 r13 或 栈 指 针 (sp_mode) ;<br />

• 其 自 身 的 r14 或 链 接 寄 存 器 (lr_mode) ;<br />

• 其 自 身 的 程 序 状 态 存 储 寄 存 器 (spsr_ mode)。<br />

在 FIQ 情 况 下 , 每 个 异 常 处 理 程 序 占 用 多 达 五 个 通 用 寄 存 器 (r8_FIQ 到<br />

r12_FIQ)。<br />

每 个 异 常 处 理 程 序 必 须 保 证 在 退 出 时 将 其 它 寄 存 器 恢 复 到 其 初 始 内 容 。 可 通 过<br />

将 该 处 理 程 序 必 须 使 用 的 任 意 寄 存 器 的 内 容 存 储 在 其 栈 中 , 并 在 返 回 时 恢 复 这<br />

些 寄 存 器 的 内 容 即 可 实 现 一 点 目 的 。 如 果 你 正 在 使 用 Angel 或 <strong>ARM</strong>ulator ® , 将<br />

自 动 设 置 所 需 要 的 栈 。 否 则 , 需 自 行 设 置 。<br />

备 注<br />

提 供 的 汇 编 程 序 没 有 预 先 声 明 register_mode 格 式 的 符 号 寄 存 器 名 称 。 要 使 用 该<br />

格 式 , 必 须 用 RN 汇 编 程 序 命 令 声 明 其 相 应 的 符 号 名 称 。 例 如 , lr_FIQ RN r14 声<br />

明 了 r14 寄 存 器 的 符 号 名 称 为 lr_FIQ。 有 关 RN 命 令 的 更 多 信 息 , 请 参 阅<br />

<strong>RealView</strong> 编 译 工 具 2.0 版 汇 编 程 序 指 南 有 关 命 令 的 章 节 。<br />

6.1.3 异 常 优 先 级<br />

当 几 个 异 常 同 时 发 生 时 , 它 们 以 固 定 的 优 先 级 顺 序 处 理 。 用 户 程 序 继 续 执 行 前 ,<br />

依 次 处 理 每 个 异 常 。 所 有 异 常 均 同 时 产 生 是 不 可 能 的 。 例 如 ,“ 未 定 义 指 令 ” 和<br />

SWI 异 常 是 相 互 排 斥 的 , 因 为 两 者 均 是 通 过 执 行 一 个 指 令 而 触 发 的 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 6-3


处 理 处 理 器 异 常<br />

表 6-2 展 示 了 异 常 情 况 、 其 对 应 的 处 理 器 模 式 和 处 理 优 先 级 。<br />

由 于 “ 数 据 中 断 ” 异 常 比 FIQ 异 常 具 有 更 高 的 优 先 级 ,“ 数 据 中 断 ” 实 际 上 在<br />

处 理 FIQ 之 前 即 被 寄 存 。 进 入 了 “ 数 据 中 断 ” 处 理 程 序 , 但 是 , 控 制 权 立 即 交<br />

给 了 FIQ 处 理 程 序 。 处 理 完 FIQ 后 , 控 制 权 返 回 “ 数 据 中 断 ” 处 理 程 序 。 这 意<br />

味 着 如 果 先 处 理 FIQ, 数 据 传 输 也 不 会 发 生 漏 过 数 据 传 送 错 误 检 测 。<br />

表 6-2 异 常 优 先 级<br />

向 量 地 址 异 常 类 型 异 常 模 式 优 先 级 (1= 高 , 6= 低 )<br />

0x0 复 位 超 级 用 户 (SVC) 1<br />

0x4 未 定 义 指 令 未 定 义 6<br />

0x8 软 件 中 断 (SWI) 超 级 用 户 (SVC) 6<br />

0xC 预 取 中 断 中 断 5<br />

0x10 数 据 中 断 Abort 2<br />

0x14 保 留 不 可 用 不 可 用<br />

0x18 中 断 (IRQ) 中 断 (IRQ) 4<br />

0x1C 快 速 中 断 (FIQ) 快 速 中 断 (FIQ) 3<br />

6-4 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


处 理 处 理 器 异 常<br />

6.2 确 定 处 理 器 状 态<br />

产 生 异 常 时 , 异 常 处 理 程 序 可 能 要 确 定 处 理 器 是 在 <strong>ARM</strong> 状 态 还 是 在 Thumb 状<br />

态 。 特 别 是 SWI 处 理 程 序 , 更 需 要 读 取 处 理 器 状 态 。 通 过 检 测 SPSR 的 T 位 完<br />

成 确 定 处 理 器 状 态 。 该 位 在 Thumb 状 态 时 为 设 置 , 在 <strong>ARM</strong> 状 态 时 为 清 除 。<br />

<strong>ARM</strong> 和 Thumb 指 令 集 均 有 SWI 指 令 。 在 Thumb 状 态 下 调 用 SWI 时 , 必 须<br />

考 虑 :<br />

• 指 令 的 地 址 在 (lr - 2), 而 不 在 (lr - 4) ;<br />

• 该 指 令 本 身 为 16 位 , 因 而 需 要 半 字 节 载 入 ( 请 参 阅 图 6-1);<br />

• 在 AMR 状 态 下 , SWI 号 码 以 8 位 存 储 , 而 不 是 24 位 。<br />

图 6-1 Thumb SWI 指 令<br />

示 例 6-1 说 明 了 在 两 种 资 源 中 处 理 一 个 SWI 的 <strong>ARM</strong> 代 码 。 考 虑 如 下 要 点 :<br />

• 如 果 需 要 改 进 编 码 的 密 度 , 每 个 do_swi_x 例 程 均 可 实 行 转 换 到 Thumb 状 态<br />

并 且 能 转 换 回 来 。<br />

• 可 通 过 调 用 一 个 包 含 switch() 语 句 的 C 函 数 来 执 行 SWI 以 替 换 跳 转 表 。<br />

• 根 据 调 用 状 态 不 同 , SWI 号 码 的 处 理 也 可 能 不 同 。<br />

• Thumb 状 态 下 可 获 取 的 SWI 号 码 范 围 可 通 过 动 态 调 用 SWI 来 增 加 ( 如 第<br />

6-18 页 的 SWI 处 理 程 序 说 明 )。<br />

示 例 6-1<br />

T_bit EQU 0x20 ; Thumb bit of CPSR/SPSR, that is, bit 5.<br />

:<br />

:<br />

SWIHandler<br />

STMFD sp!, {r0-r3,r12,lr} ; Store registers.<br />

MRS r0, spsr ; Move SPSR into general purpose register.<br />

TST r0, #T_bit ; Occurred in Thumb state?<br />

LDRNEH r0,[lr,#-2]<br />

; Yes: load halfword and...<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 6-5


处 理 处 理 器 异 常<br />

BICNE r0,r0,#0xFF00 ; ...extract comment field.<br />

LDREQ r0,[lr,#-4] ; No: load word and...<br />

BICEQ r0,r0,#0xFF000000 ; ...extract comment field.<br />

; r0 now contains SWI number<br />

CMP r0, #MaxSWI ; Rangecheck<br />

LDRLS pc, [pc, r0, LSL#2] ; Jump to the appropriate routine.<br />

B SWIOutOfRange<br />

switable<br />

DCD do_swi_1<br />

DCD do_swi_2<br />

:<br />

:<br />

do_swi_1<br />

; Handle the SWI.<br />

LDMFD sp!, {r0-r3,r12,pc}^ ; Restore the registers and return.<br />

do_swi_2<br />

:<br />

6-6 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


处 理 处 理 器 异 常<br />

6.3 进 入 和 离 开 异 常<br />

本 章 说 明 了 处 理 器 对 异 常 的 反 应 , 处 理 完 异 常 后 如 何 返 回 发 生 异 常 之 处 。 根 据 异<br />

常 类 型 的 不 同 , 返 回 的 方 式 也 不 同 。<br />

能 够 处 理 Thumb 代 码 的 处 理 器 与 不 能 处 理 Thumb 代 码 的 处 理 器 使 用 相 同 的 基 本<br />

异 常 处 理 机 理 。 异 常 造 成 下 一 条 指 令 要 从 相 应 的 向 量 表 入 口 读 取 。<br />

Thumb 状 态 和 <strong>ARM</strong> 状 态 使 用 同 一 向 量 表 。 处 理 器 对 异 常 的 反 应 所 描 述 的 异 常 处<br />

理 过 程 中 增 加 了 转 至 <strong>ARM</strong> 的 初 始 步 骤 。<br />

当 编 写 适 合 于 能 处 理 Thumb 代 码 的 处 理 器 的 异 常 处 理 程 序 时 , 必 须 考 虑 额 外 的<br />

因 素 , 这 些 已 被 明 显 标 出 。<br />

6.3.1 处 理 器 对 异 常 的 反 应<br />

产 生 异 常 时 , 处 理 器 采 取 如 下 动 作 :<br />

1. 将 要 处 理 的 异 常 模 式 的 当 前 程 序 状 态 寄 存 器 (CPSR) 复 制 到 程 序 状 态 存 储<br />

寄 存 器 (SPSR)。 因 而 保 存 了 当 前 模 式 、 中 断 屏 蔽 和 条 件 标 志 。<br />

2. 仅 限 于 能 处 理 Thumb 代 码 的 处 理 器 , 转 至 <strong>ARM</strong> 状 态 。<br />

3. 请 改 变 相 应 的 CPRS 模 式 位 以 便 :<br />

• 改 变 相 应 的 模 式 及 该 模 式 下 相 应 编 组 寄 存 器 中 的 映 射 。<br />

• 禁 用 中 断 。 发 生 中 断 时 , 禁 用 IRQ。 发 生 FIQ 时 和 在 复 位 时 , 禁 用<br />

FIQ。<br />

4. 设 置 lr_mode 到 返 回 地 址 , 如 第 6-9 页 的 返 回 地 址 和 返 回 指 令 中 所 定 义 。<br />

5. 将 程 序 计 数 器 设 置 至 异 常 向 量 地 址 。<br />

对 于 不 能 处 理 Thumb 代 码 的 <strong>ARM</strong> 处 理 器 , 这 将 强 行 跳 转 至 相 应 的 异 常 处<br />

理 程 序 。<br />

对 于 能 处 理 Thumb 代 码 的 处 理 器 , 步 骤 2 中 由 Thumb 状 态 转 至 <strong>ARM</strong> 状 态<br />

保 证 了 安 装 在 该 向 量 地 址 ( 跳 转 或 与 PC 相 关 的 载 入 ) 的 <strong>ARM</strong> 指 令 能 够<br />

正 确 读 取 、 解 码 和 执 行 。 这 将 迫 使 跳 转 至 高 层 胶 合 代 码 , 该 胶 合 代 码 必 须<br />

用 <strong>ARM</strong> 代 码 编 写 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 6-7


处 理 处 理 器 异 常<br />

6.3.2 从 异 常 处 理 程 序 的 返 回<br />

从 异 常 返 回 的 方 法 取 决 于 该 异 常 处 理 程 序 使 用 或 不 使 用 堆 操 作 。 在 两 种 情 况 下 ,<br />

要 返 回 到 异 常 发 生 处 后 继 续 执 行 , 异 常 处 理 程 序 必 须 :<br />

• 从 spsr_mode 恢 复 CPSR ;<br />

• 使 用 存 储 在 lr_mode 中 的 返 回 地 址 恢 复 程 序 计 数 器 。<br />

对 于 不 需 要 将 目 的 模 式 寄 存 器 从 堆 中 恢 复 的 简 单 返 回 , 通 过 执 行 如 下 数 据 处 理<br />

指 令 , 异 常 处 理 程 序 完 成 这 些 操 作 , 它 们 是 :<br />

• 设 置 S 标 志 ;<br />

• 用 目 的 寄 存 器 恢 复 程 序 计 数 器 。<br />

所 需 的 返 回 指 令 取 决 于 异 常 的 类 型 。 有 关 如 何 从 每 种 类 型 的 异 常 返 回 的 说 明 , 请<br />

参 阅 第 6-9 页 的 返 回 地 址 和 返 回 指 令 。<br />

备 注<br />

不 必 从 复 位 处 理 程 序 返 回 , 因 为 复 位 处 理 程 序 直 接 执 行 主 代 码 。<br />

处 理 异 常 时 , 如 果 异 常 处 理 程 序 入 口 代 码 使 用 了 堆 来 存 储 必 须 保 留 的 寄 存 器 , 可<br />

通 过 使 用 装 载 多 个 带 ^ 限 定 符 的 指 令 来 返 回 。 异 常 处 理 程 序 可 使 用 一 条 指 令 返<br />

回 , 例 如 使 用 :<br />

LDMFD sp!,{r0-r12,pc}^<br />

如 果 它 将 如 下 内 容 存 储 在 堆 中 :<br />

• 调 用 处 理 程 序 时 将 使 用 所 有 的 工 作 寄 存 器 ;<br />

• 为 产 生 与 下 面 说 明 的 数 据 处 理 指 令 相 同 的 效 果 而 修 改 链 接 寄 存 器 。<br />

^ 限 定 符 指 定 从 SPSR 中 恢 复 CPSR。 仅 在 特 权 模 式 下 使 用 。 有 关 LDM 和 STM 的 堆<br />

执 行 , 请 在 <strong>RealView</strong> 编 译 工 具 2.0 版 汇 编 程 序 指 南 中 参 阅 介 绍 堆 操 作 的 更 多 一<br />

般 信 息 。<br />

6-8 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


处 理 处 理 器 异 常<br />

6.3.3 返 回 地 址 和 返 回 指 令<br />

产 生 异 常 时 由 程 序 计 数 器 指 向 的 实 际 位 置 取 决 于 异 常 的 类 型 。 返 回 地 址 可 能 不<br />

必 是 程 序 计 数 器 指 向 的 下 一 条 指 令 。<br />

如 果 异 常 发 生 在 <strong>ARM</strong> 状 态 , 处 理 器 则 将 (PC - 4) 存 储 在 lr_ mode。 但 是 , 对 于<br />

在 Thumb 状 态 下 发 生 的 异 常 , 处 理 器 为 每 个 异 常 类 型 自 动 存 储 一 个 不 同 的 值 。<br />

这 样 的 调 整 是 必 需 的 , 因 为 Thumb 指 令 仅 占 用 半 个 字 , 而 不 像 <strong>ARM</strong> 指 令 占 用<br />

整 个 字 。<br />

如 果 处 理 器 不 对 此 进 行 修 正 , 处 理 程 序 必 须 确 定 处 理 器 原 始 状 态 并 使 用 不 同 指<br />

令 返 回 到 Thumb 代 码 , 而 不 是 返 回 <strong>ARM</strong> 代 码 。 然 而 , 通 过 这 样 的 调 整 , 处 理<br />

器 能 使 处 理 程 序 使 用 一 条 指 令 完 成 正 确 返 回 , 而 不 用 考 虑 异 常 发 生 时 处 理 器 的<br />

状 态 ( 是 <strong>ARM</strong> 或 Thumb)。<br />

下 面 的 章 节 较 详 细 地 说 明 了 每 一 种 异 常 类 型 如 何 从 处 理 代 码 正 确 返 回 的 指 令 。<br />

从 SWI 和 未 定 义 指 令 处 理 程 序 返 回<br />

SWI 和 未 定 义 指 令 异 常 是 由 指 令 本 身 造 成 的 , 因 此 , 处 理 异 常 时 , 程 序 计 数 器 保<br />

持 不 变 。 处 理 器 将 (PC - 4) 存 储 在 lr_ mode 中 。 因 而 使 lr_mode 指 向 下 一 条 要 执<br />

行 的 指 令 。 要 从 lr 中 恢 复 程 序 计 数 器 , 则 使 用 :<br />

MOVS<br />

pc, lr<br />

从 处 理 程 序 返 回 控 制 权 。<br />

将 返 回 地 址 推 入 堆 中 并 在 返 回 时 将 其 弹 出 的 处 理 程 序 入 口 和 出 口 代 码 为 :<br />

STMFD<br />

;...<br />

LDMFD<br />

sp!,{reglist,lr}<br />

sp!,{reglist,pc}^<br />

对 于 在 Thumb 状 态 下 发 生 的 异 常 , 处 理 程 序 返 回 指 令 (MOVS pc,lr) 将 程 序 计 数 器<br />

指 向 下 一 条 要 执 行 指 令 的 地 址 。 这 是 在 (PC - 2), 因 此 处 理 器 存 储 在 lr_mode 中<br />

的 值 为 (PC - 2)。<br />

从 FIQ 和 IRQ 处 理 程 序 返 回<br />

执 行 完 每 一 条 指 令 后 , 处 理 器 检 测 中 断 管 脚 是 否 为 LOW ( 电 平 ), 以 及 CPSR<br />

中 断 禁 用 位 是 否 为 清 除 。 结 果 , 仅 在 程 序 计 数 器 被 更 新 后 才 发 生 IRQ 或 FIQ 异<br />

常 。 处 理 器 将 (PC - 4) 存 储 在 lr_mode 中 。 使 lr_mode 指 向 发 生 异 常 时 尚 未 完 成<br />

的 一 条 指 令 。 处 理 程 序 完 成 后 , 必 须 从 lr_mode 指 向 的 上 一 条 指 令 处 继 续 运 行 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 6-9


处 理 处 理 器 异 常<br />

该 继 续 执 行 地 址 较 lr_mode 中 的 地 址 少 一 个 字 ( 四 个 字 节 ), 因 此 , 其 返 回 指<br />

令 为 :<br />

SUBS pc, lr, #4<br />

将 返 回 地 址 推 入 堆 中 并 在 返 回 时 将 其 弹 出 的 处 理 程 序 入 口 和 出 口 代 码 为 :<br />

SUB<br />

STMFD<br />

;...<br />

LDMFD<br />

lr,lr,#4<br />

sp!,{reglist,lr}<br />

sp!,{reglist,pc}^<br />

对 于 发 生 在 Thumb 状 态 下 的 异 常 , 处 理 程 序 返 回 指 令 (SUBS pc,lr,#4) 改 变 了 程<br />

序 计 数 器 , 将 其 指 向 下 一 条 要 执 行 指 令 的 地 址 。 由 于 程 序 计 数 器 的 更 新 是 在 处 理<br />

异 常 之 前 完 成 , 下 一 条 指 令 应 在 (PC - 4) 。 因 此 , 处 理 器 存 储 在 lr_mode 的 值 为<br />

PC 。<br />

从 预 取 中 断 处 理 程 序 返 回<br />

如 果 处 理 器 试 图 在 非 法 地 址 取 指 令 , 则 该 指 令 被 标 志 为 无 效 。 继 续 执 行 已 经 在 流<br />

水 线 中 的 指 令 至 遇 到 产 生 “ 预 取 中 断 ” 处 的 无 效 指 令 为 止 。<br />

如 有 将 虚 拟 存 储 器 位 置 映 射 到 该 物 理 存 储 器 的 指 令 , 异 常 处 理 程 序 将 无 映 射 关<br />

系 的 指 令 装 入 物 理 存 储 器 并 使 用 MMU。 然 后 , 处 理 程 序 必 须 返 回 , 再 次 使 着 运<br />

行 产 生 异 常 的 指 令 。 现 在 装 入 并 执 行 指 令 。<br />

因 为 发 出 预 取 中 断 时 程 序 计 数 器 还 没 有 被 更 新 , 所 以 lr_ABT 指 向 产 生 异 常 的 下<br />

一 条 指 令 。 处 理 程 序 必 须 返 回 至 lr_ABT - 4 的 指 令 , 请 使 用 下 列 指 令 :<br />

SUBS pc,lr, #4<br />

将 返 回 地 址 推 入 堆 中 并 在 返 回 时 将 其 弹 出 的 处 理 程 序 入 口 和 出 口 代 码 为 :<br />

SUB<br />

STMFD<br />

;...<br />

LDMFD<br />

lr,lr,#4<br />

sp!,{reglist,lr}<br />

sp!,{reglist,pc}^<br />

对 于 发 生 在 Thumb 状 态 下 的 异 常 , 处 理 程 序 返 回 指 令 (SUBS pc,lr,#4) 改 变 了 程<br />

序 计 数 器 , 将 其 指 向 产 生 中 断 指 令 的 地 址 。 由 于 程 序 计 数 器 的 更 新 不 是 在 处 理 异<br />

常 之 前 完 成 , 中 断 指 令 应 在 (PC - 4)。 因 此 , 处 理 器 存 储 在 lr_mode 的 值 为 PC。<br />

6-10 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


处 理 处 理 器 异 常<br />

从 数 据 中 断 处 理 程 序 返 回<br />

当 装 入 或 存 储 指 令 试 图 访 问 存 储 器 时 , 程 序 计 数 器 被 更 新 。 (PC - 4) 的 存 储 值 指<br />

向 产 生 异 常 地 址 处 的 第 二 条 指 令 。MMU( 如 果 有 ) 将 相 应 地 址 映 射 至 物 理 存 储<br />

器 , 处 理 程 序 必 须 返 回 到 原 来 中 断 的 指 令 , 以 便 进 行 第 二 次 执 行 尝 试 。 因 此 , 返<br />

回 地 址 较 lr_ABT 中 少 两 个 字 ( 八 个 字 节 ), 使 用 如 下 返 回 指 令 :<br />

SUBS pc, lr, #8<br />

将 返 回 地 址 推 入 堆 中 并 在 返 回 时 将 其 弹 出 的 处 理 程 序 入 口 和 出 口 代 码 为 :<br />

SUB<br />

STMFD<br />

;...<br />

LDMFD<br />

lr,lr,#8<br />

sp!,{reglist,lr}<br />

sp!,{reglist,pc}^<br />

对 于 发 生 在 Thumb 状 态 下 的 异 常 , 处 理 程 序 返 回 指 令 (SUBS pc,lr,#8) 改 变 了 程<br />

序 计 数 器 , 将 其 指 向 产 生 中 断 指 令 的 地 址 。 由 于 程 序 计 数 器 的 更 新 是 在 处 理 异 常<br />

之 前 , 中 断 指 令 应 在 (PC - 6)。 因 此 , 处 理 器 存 储 在 lr_mode 的 值 为 (PC + 2)。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 6-11


处 理 处 理 器 异 常<br />

6.4 处 理 异 常<br />

顶 层 胶 合 代 码 必 须 将 处 理 器 的 状 态 和 任 何 所 需 的 寄 存 器 存 储 在 堆 中 。 然 后 可 以<br />

按 下 面 的 选 项 编 写 异 常 处 理 程 序 。<br />

• 完 全 以 <strong>ARM</strong> 代 码 编 写 异 常 处 理 程 序 。<br />

• 执 行 BX ( 跳 转 和 互 换 ) 转 到 处 理 异 常 的 Thumb 代 码 例 程 。 为 从 异 常 中 返<br />

回 , 该 例 程 必 须 返 回 到 <strong>ARM</strong> 胶 合 代 码 , 因 为 Thumb 指 令 集 没 有 要 求 从<br />

spsr 中 恢 复 cpsr 的 指 令 。<br />

第 二 个 策 略 如 图 6-2 所 示 。 有 关 如 何 将 <strong>ARM</strong> 和 Thumb 代 码 以 这 种 方 式 结 合 的 详<br />

细 说 明 , 请 参 阅 第 4 章 <strong>ARM</strong> 和 Thumb 交 互 操 作 。<br />

图 6-2 在 <strong>ARM</strong> 或 Thumb 状 态 下 处 理 异 常<br />

6-12 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


处 理 处 理 器 异 常<br />

6.5 安 装 异 常 处 理 程 序<br />

必 须 将 任 何 新 的 异 常 处 理 程 序 安 装 在 向 量 表 中 。 安 装 完 成 后 , 不 论 什 么 时 候 产 生<br />

相 应 的 异 常 , 都 会 执 行 新 的 处 理 程 序 。<br />

可 以 按 以 下 方 法 安 装 异 常 处 理 程 序 :<br />

跳 转 指 令<br />

这 是 转 到 异 常 处 理 程 序 最 简 单 的 方 法 。 向 量 表 中 的 每 个 入 口 都 包 括<br />

一 个 能 够 转 到 处 理 例 程 的 跳 转 。 但 是 , 这 种 方 法 确 实 有 局 限 性 。 因<br />

跳 转 指 令 相 对 于 PC 仅 有 32MB 的 范 围 , 在 某 些 存 储 器 组 织 情 况<br />

下 , 该 跳 转 可 能 无 法 转 到 处 理 程 序 。<br />

6.5.1 在 复 位 时 安 装 处 理 程 序<br />

装 入 PC 指 令<br />

使 用 该 方 法 , 强 制 程 序 计 数 器 直 接 指 向 处 理 程 序 的 方 法 有 :<br />

1. 将 处 理 程 序 的 绝 对 地 址 存 储 在 合 适 的 存 储 器 位 置 ( 在 向 量 地<br />

址 的 4BK 范 围 内 )。<br />

2. 将 一 个 指 令 存 放 在 向 量 中 , 该 向 量 装 入 包 含 所 选 存 储 器 位 置<br />

的 程 序 计 数 器 。<br />

如 果 应 用 程 序 不 是 靠 调 试 器 或 调 试 监 督 程 序 启 动 程 序 的 执 行 , 可 以 使 用 汇 编 语<br />

言 复 位 ( 或 启 动 ) 代 码 直 接 装 入 向 量 表 。<br />

如 果 ROM 是 在 存 储 器 的 0x0 位 置 , 则 可 在 代 码 的 起 始 处 为 每 个 向 量 分 配 一 个 跳<br />

转 语 句 。 如 果 FIQ 处 理 程 序 是 直 接 从 0x1C 运 行 的 , 则 也 可 将 FIQ 处 理 程 序 包 含<br />

在 其 中 ( 请 参 阅 第 6-27 页 的 中 断 处 理 程 序 )。<br />

示 例 6-2 展 示 了 如 果 它 们 位 于 ROM 的 零 地 址 时 建 立 向 量 的 代 码 。 可 替 换 装 入 的<br />

跳 转 语 句 。<br />

示 例 6-2<br />

Vector_Init_Block<br />

LDR<br />

LDR<br />

LDR<br />

LDR<br />

LDR<br />

NOP<br />

pc, Reset_Addr<br />

pc, Undefined_Addr<br />

pc, SWI_Addr<br />

pc, Prefetch_Addr<br />

pc, Abort_Addr<br />

;Reserved vector<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 6-13


处 理 处 理 器 异 常<br />

LDR<br />

LDR<br />

pc, IRQ_Addr<br />

pc, FIQ_Addr<br />

Reset_Addr DCD Start_Boot<br />

Undefined_Addr DCD Undefined_Handler<br />

SWI_Addr DCD SWI_Handler<br />

Prefetch_Addr DCD Prefetch_Handler<br />

Abort_Addr DCD Abort_Handler<br />

DCD 0 ;Reserved vector<br />

IRQ_Addr DCD IRQ_Handler<br />

FIQ_Addr DCD FIQ_Handler<br />

复 位 状 态 下 , 必 须 使 ROM 处 在 0x0 位 置 。 复 位 代 码 可 将 RAM 映 射 到 0x0 位 置 。<br />

这 样 做 之 前 , 它 需 从 ROM 的 某 个 区 域 将 该 向 量 ( 根 据 需 要 还 有 FIQ 处 理 程 序 )<br />

复 制 到 RAM 中 。<br />

在 此 情 况 下 , 必 须 用 一 条 LDR pc 指 令 为 复 位 处 理 程 序 确 定 地 址 , 以 便 使 复 位 向<br />

量 代 码 能 独 立 定 位 。<br />

示 例 6-3 将 第 6-13 页 的 示 例 6-2 给 出 的 向 量 复 制 到 了 RAM 中 的 向 量 表 。<br />

示 例 6-3<br />

MOV r8, #0<br />

ADR r9, Vector_Init_Block<br />

LDMIA r9!,{r0-r7} ;Copy the vectors (8 words)<br />

STMIA r8!,{r0-r7}<br />

LDMIA r9!,{r0-r7} ;Copy the DCD'ed addresses<br />

STMIA r8!,{r0-r7} ;(8 words again)<br />

此 外 , 还 可 使 用 分 散 载 入 机 制 来 定 义 向 量 表 的 载 入 和 执 行 地 址 。 在 此 情 况 下 ,C<br />

库 将 为 您 复 制 向 量 表 ( 请 参 阅 第 2 章 嵌 入 式 软 件 开 发 )。<br />

6-14 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


处 理 处 理 器 异 常<br />

6.5.2 从 C 安 装 处 理 程 序<br />

开 发 过 程 中 有 时 必 需 从 主 应 用 程 序 直 接 将 异 常 处 理 程 序 安 装 在 向 量 中 。 结 果 , 所<br />

需 的 指 令 编 码 必 须 被 写 到 相 应 的 向 量 地 址 中 。 这 可 由 跳 转 和 载 入 PC 两 种 方 法 来<br />

转 到 该 处 理 程 序 。<br />

跳 转 方 法<br />

所 需 的 指 令 可 按 如 下 方 法 构 成 :<br />

1. 获 取 异 常 处 理 程 序 的 地 址 。<br />

2. 减 去 相 应 向 量 的 地 址 。<br />

3. 减 去 0x8 以 便 预 取 。<br />

4. 将 结 果 右 移 两 位 给 出 一 个 字 的 偏 移 , 而 不 是 一 个 字 节 的 偏 移 。<br />

5. 测 试 其 高 八 位 为 清 除 , 确 保 结 果 仅 为 24 位 长 ( 因 为 跳 转 的 偏 移 被 限 制 为<br />

此 长 度 )。<br />

6. 把 它 与 0xEA000000 ( 跳 转 指 令 操 作 码 ) 进 行 逻 辑 “ 或 ” 运 算 , 生 成 要 放 在<br />

向 量 中 的 值 。<br />

示 例 6-4 展 示 了 实 现 该 算 法 的 C 函 数 。 它 占 用 了 以 下 几 个 自 变 量 :<br />

• 处 理 程 序 的 地 址 ;<br />

• 将 处 理 程 序 安 装 在 其 中 的 向 量 地 址 。<br />

该 函 数 可 以 安 装 处 理 程 序 并 返 回 该 向 量 的 初 始 内 容 。 这 个 结 果 可 以 用 来 为 一 个<br />

特 定 的 异 常 创 建 一 系 列 的 处 理 程 序 。 详 细 信 息 请 参 阅 第 6-41 页 的 链 结 异 常 处 理<br />

程 序 。<br />

示 例 6-4<br />

unsigned Install_Handler (unsigned routine, unsigned *vector)<br />

/* Updates contents of 'vector' to contain branch instruction */<br />

/* to reach ’routine’ from ’vector’. Function return value is */<br />

/* original contents of 'vector'.*/<br />

/* NB: ’Routine’ must be within range of 32MB from ’vector’.*/<br />

{ unsigned vec, oldvec;<br />

vec = ((routine - (unsigned)vector - 0x8)>>2);<br />

if ((vec & 0xFF000000))<br />

{<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 6-15


处 理 处 理 器 异 常<br />

}<br />

/* diagnose the fault */<br />

prinf ("Installation of Handler failed");<br />

exit (1);<br />

}<br />

vec = 0xEA000000 | vec;<br />

oldvec = *vector;<br />

*vector = vec;<br />

return (oldvec);<br />

以 下 代 码 调 用 它 来 安 装 IRQ 处 理 程 序 :<br />

unsigned *irqvec = (unsigned *)0x18;<br />

Install_Handler ((unsigned)IRQHandler, irqvec);<br />

在 此 情 况 下 , 将 丢 弃 返 回 的 初 始 IRQ 向 量 内 容 。<br />

装 入 PC 方 法<br />

所 需 的 指 令 可 按 如 下 方 法 构 成 :<br />

1. 获 取 包 含 异 常 处 理 程 序 地 址 那 个 字 的 地 址 。<br />

2. 减 去 相 应 向 量 的 地 址 。<br />

3. 减 去 0x8 以 便 预 取 。<br />

4. 检 查 其 结 果 能 否 用 12 位 表 示 。<br />

5. 把 它 与 0xe59FF000(LDR pc, [pc,#offset] 的 操 作 码 ) 进 行 逻 辑 “ 或 ” 运 算 ,<br />

生 成 要 放 在 向 量 中 的 值 。<br />

6. 将 异 常 处 理 程 序 的 地 址 放 入 该 存 储 位 置 。<br />

示 例 6-5 展 示 了 实 现 了 该 方 法 的 C 例 程 。<br />

示 例 6-5<br />

unsigned Install_Handler (unsigned location, unsigned *vector)<br />

/* Updates contents of 'vector' to contain LDR pc, [pc, #offset] */<br />

/* instruction to cause long branch to address in 'location'. */<br />

/* Function return value is original contents of 'vector'. */<br />

{ unsigned vec, oldvec;<br />

vec = ((unsigned)location - (unsigned)vector - 0x8) | 0xe59ff000;<br />

oldvec = *vector;<br />

6-16 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


处 理 处 理 器 异 常<br />

}<br />

*vector = vec;<br />

return (oldvec);<br />

以 下 代 码 调 用 它 来 安 装 IRQ 处 理 程 序 :<br />

unsigned *irqvec = (unsigned *)0x18;<br />

static unsigned pIRQ_Handler = (unsigned)IRQ_handler<br />

Install_Handler (&pIRQHandler, irqvec);<br />

在 此 示 例 中 , 返 回 的 初 始 IRQ 向 量 内 容 被 再 次 被 丢 弃 , 但 可 用 它 来 创 建 一 系 列<br />

处 理 程 序 。 有 关 详 细 信 息 请 参 阅 第 6-41 页 的 链 结 异 常 处 理 程 序 。<br />

备 注<br />

如 果 正 在 使 用 带 单 独 指 令 和 数 据 缓 存 的 处 理 器 , 例 如 Strong<strong>ARM</strong> ® 或 <strong>ARM</strong>940T,<br />

必 须 保 证 缓 存 一 致 性 问 题 不 会 阻 碍 使 用 新 的 向 量 内 容 。<br />

为 确 保 新 的 向 量 内 容 写 入 主 存 储 器 中 , 必 须 清 除 数 据 缓 存 ( 或 至 少 其 入 口 含 有<br />

修 改 过 的 向 量 )。 然 后 必 须 将 指 令 缓 存 刷 新 , 确 保 可 从 主 存 储 器 中 读 取 新 的 向 量<br />

内 容 。<br />

有 关 清 除 和 刷 新 缓 存 操 作 的 详 细 说 明 , 请 参 阅 目 标 处 理 器 的 技 术 参 考 手 册 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 6-17


处 理 处 理 器 异 常<br />

6.6 SWI 处 理 程 序<br />

进 入 SWI 处 理 程 序 时 , 必 须 设 定 哪 个 SWI 将 被 调 用 。 该 信 息 可 存 储 在 指 令 本 身<br />

的 0-23 位 , 如 图 6-3 所 示 , 或 将 其 传 递 到 一 个 整 数 寄 存 器 , 通 常 为 r0-r3 中 的<br />

一 个 。<br />

图 6-3 <strong>ARM</strong> SWI 指 令<br />

最 高 层 的 SWI 处 理 程 序 可 载 入 与 链 接 寄 存 器 关 联 的 SWI 指 令 (LDR swi, [lr,<br />

#-4]) 。 请 用 汇 编 语 言 、 C/C++ 内 联 或 嵌 入 汇 编 语 言 编 写 。<br />

处 理 程 序 必 须 首 先 将 导 致 异 常 的 SWI 指 令 装 入 寄 存 器 。 在 这 一 点 上 , lr_SVC 存<br />

储 着 SWI 指 令 的 下 一 个 指 令 的 地 址 , 因 此 SWI 使 用 下 面 的 指 令 被 载 入 到 了 寄 存 器<br />

( 此 例 中 为 r0):<br />

LDR r0, [lr,#-4]<br />

然 后 , 处 理 程 序 可 检 查 字 段 位 , 以 决 定 所 需 的 操 作 。 通 过 清 除 操 作 码 的 高 八 位 来<br />

提 取 SWI 编 号 。<br />

BIC r0, r0, #0xFF000000<br />

示 例 6-6 展 示 了 如 何 将 这 些 指 令 结 合 形 成 一 个 最 高 层 的 SWI 处 理 程 序 。<br />

有 关 处 理 <strong>ARM</strong> 状 态 和 Thumb 状 态 的 SWI 指 令 的 处 理 程 序 示 例 , 请 参 阅 第 6-5 页<br />

的 确 定 处 理 器 状 态 。<br />

示 例 6-6<br />

AREA TopLevelSwi, CODE, READONLY ; Name this block of code.<br />

EXPORT SWI_Handler<br />

SWI_Handler<br />

STMFD sp!,{r0-r12,lr} ; Store registers.<br />

LDR r0,[lr,#-4] ; Calculate address of SWI instruction and load it into r0.<br />

BIC r0,r0,#0xff000000 ; Mask off top 8 bits of instruction to give SWI number.<br />

;<br />

; Use value in r0 to determine which SWI routine to execute.<br />

6-18 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


处 理 处 理 器 异 常<br />

;<br />

LDMFD sp!, {r0-r12,pc}^ ; Restore registers and return.<br />

END<br />

; Mark end of this file.<br />

6.6.1 汇 编 语 言 编 写 的 SWI 处 理 程 序<br />

调 用 所 需 SWI 编 号 的 处 理 程 序 , 最 简 单 的 方 法 是 使 用 跳 转 表 。 如 果 r0 中 有 SWI<br />

编 号 , 示 例 6-7 中 的 代 码 可 被 插 在 第 6-18 页 的 示 例 6-6 给 出 的 最 高 层 处 理 程 序<br />

中 , 插 入 位 置 在 BIC 指 令 之 后 。<br />

示 例 6-7 SWI 跳 转 表<br />

CMP r0,#MaxSWI ; Range check<br />

LDRLS pc, [pc,r0,LSL #2]<br />

B SWIOutOfRange<br />

SWIJumpTable<br />

DCD SWInum0<br />

DCD SWInum1<br />

; DCD for each of other SWI routines<br />

SWInum0<br />

; SWI number 0 code<br />

B EndofSWI<br />

SWInum1<br />

; SWI number 1 code<br />

B EndofSWI<br />

; Rest of SWI handling code<br />

;<br />

EndofSWI<br />

; Return execution to top level<br />

; SWI handler so as to restore<br />

; registers and return to program.<br />

6.6.2 C 语 言 和 汇 编 语 言 编 写 的 SWI 处 理 程 序<br />

虽 然 最 高 层 的 处 理 程 序 总 是 用 <strong>ARM</strong> 汇 编 语 言 编 写 , 但 处 理 每 一 SWI 的 例 程 却<br />

是 既 可 用 汇 编 语 言 编 写 , 又 可 用 C 语 言 来 编 写 。 有 关 限 制 情 况 的 说 明 , 请 参 阅<br />

第 6-21 页 的 在 超 级 用 户 模 式 下 使 用 SWI。<br />

最 高 层 的 处 理 程 序 通 过 使 用 一 个 BL ( 链 接 跳 转 ) 指 令 跳 转 到 相 应 的 C 函 数 。 由<br />

于 SWI 编 号 被 汇 编 语 言 例 程 装 入 了 r0, 并 将 其 作 为 第 一 个 参 数 ( 与 “<strong>ARM</strong> 过<br />

程 调 用 标 准 ” 一 致 ) 传 递 至 C 函 数 。 该 函 数 可 以 使 用 这 个 值 , 例 如 , 一 个 switch()<br />

语 句 。<br />

可 在 第 6-18 页 的 示 例 6-6 的 SWI_Handler 例 程 中 加 入 下 列 行 :<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 6-19


处 理 处 理 器 异 常<br />

BL C_SWI_Handler ; Call C routine to handle the SWI<br />

示 例 6-8 展 示 了 如 何 实 现 C 函 数 。<br />

示 例 6-8<br />

void C_SWI_handler (unsigned number)<br />

{ switch (number)<br />

{case 0 : /* SWI number 0 code */<br />

break;<br />

case 1 : /* SWI number 1 code */<br />

break;<br />

:<br />

:<br />

default : /* Unknown SWI - report error */<br />

}<br />

}<br />

超 级 用 户 堆 的 空 间 可 能 是 有 限 的 , 因 此 要 避 免 使 用 需 要 大 量 堆 空 间 的 函 数 。<br />

可 将 值 传 入 和 传 出 用 C 语 言 编 写 的 SWI 处 理 程 序 中 , 前 提 条 件 是 最 高 层 处 理 程<br />

序 将 堆 指 针 值 作 为 第 二 参 数 (r1 中 ) 传 递 到 C 函 数 中 :<br />

MOV r1, sp ; Second parameter to C routine...<br />

; ...is pointer to register values.<br />

BL C_SWI_Handler ; Call C routine to handle the SWI<br />

然 后 更 新 C 函 数 以 访 问 它 :<br />

void C_SWI_handler(unsigned number, unsigned *reg)<br />

现 在 ,C 函 数 在 主 应 用 程 序 代 码 ( 请 参 阅 第 6-21 页 的 图 6-4) 中 遇 到 SWI 指 令 时<br />

即 可 存 取 存 储 在 寄 存 器 中 的 值 了 。 它 可 从 其 中 读 取 :<br />

value_in_reg_0 = reg [0];<br />

value_in_reg_1 = reg [1];<br />

value_in_reg_2 = reg [2];<br />

value_in_reg_3 = reg [3];<br />

并 可 写 入 其 中 :<br />

reg [0] = updated_value_0;<br />

reg [1] = updated_value_1;<br />

reg [2] = updated_value_2;<br />

reg [3] = updated_value_3;<br />

6-20 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


处 理 处 理 器 异 常<br />

这 使 已 被 更 新 的 值 写 入 了 堆 的 相 应 位 置 , 然 后 通 过 最 高 层 处 理 程 序 将 其 恢 复 到<br />

寄 存 器 中 。<br />

图 6-4 存 取 超 级 用 户 堆<br />

6.6.3 在 超 级 用 户 模 式 下 使 用 SWI<br />

当 执 行 SWI 指 令 时 :<br />

1. 处 理 器 进 入 超 级 用 户 模 式<br />

2. CPSR 被 存 储 在 spsr_SVC 中 。<br />

3. 返 回 地 址 被 存 储 在 lr_SVC 中 ( 请 参 阅 第 6-7 页 的 处 理 器 对 异 常 的 反 应 )。<br />

如 处 理 器 已 经 处 在 超 级 用 户 模 式 下 , lr_SVC 和 spsr_SVC 被 破 坏 。<br />

在 超 级 用 户 模 式 下 , 如 果 调 用 SWI, 则 需 存 储 lr_SVC 和 spsr_SVC, 以 确 保 链 接 寄<br />

存 器 和 SPSR 中 的 初 始 值 不 被 丢 失 。 例 如 , 一 个 特 定 SWI 编 号 的 处 理 程 序 例 程<br />

调 用 了 另 一 个 SWI, 必 须 确 保 该 该 处 理 程 序 例 程 将 lr_SVC 和 spsr_SVC 存 储 在 堆<br />

中 。 它 确 保 了 处 理 程 序 的 每 一 次 调 用 都 保 存 了 返 回 到 调 用 SWI 指 令 所 需 要 的 信<br />

息 。 示 例 6-9 展 示 了 如 何 实 现 的 方 法 。<br />

示 例 6-9 SWI 处 理 程 序<br />

STMFD sp!,{r0-r3,r12,lr} ; Store registers.<br />

MOV r1, sp ; Set pointer to parameters.<br />

MRS r0, spsr ; Get spsr.<br />

STMFD sp!, {r0} ; Store spsr onto stack. This is only really needed in case of<br />

; nested SWIs.<br />

; the next two instructions only work for SWI calls from <strong>ARM</strong> state.<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 6-21


处 理 处 理 器 异 常<br />

; See Example 6-18 on page 6-33 for a version that works for calls from either <strong>ARM</strong> or Thumb.<br />

LDR r0,[lr,#-4] ; Calculate address of SWI instruction and load it into r0.<br />

BIC r0,r0,#0xFF000000 ; Mask off top 8 bits of instruction to give SWI number.<br />

; r0 now contains SWI number<br />

; r1 now contains pointer to stacked registers<br />

BL C_SWI_Handler ; Call C routine to handle the SWI.<br />

LDMFD sp!, {r0} ; Get spsr from stack.<br />

MSR spsr_cf, r0 ; Restore spsr.<br />

LDMFD sp!, {r0-r3,r12,pc}^ ; Restore registers and return.<br />

C 和 C++ 编 写 的 嵌 套 SWI<br />

可 用 C or C++ 汇 编 语 言 编 写 嵌 套 的 SWI。 由 <strong>ARM</strong> 编 译 程 序 生 成 的 代 码 按 需 要<br />

存 储 和 载 入 lr_SVC。<br />

6.6.4 从 应 用 程 序 调 用 SWI<br />

可 从 汇 编 语 言 或 C/C++ 调 用 SWI。<br />

在 汇 编 语 言 中 , 设 定 所 有 必 须 的 值 并 发 出 相 关 的 SWI。 例 如 :<br />

MOV r0, #65 ; load r0 with the value 65<br />

SWI 0x0 ; Call SWI 0x0 with parameter value in r0<br />

几 乎 像 所 有 的 <strong>ARM</strong> 指 令 那 样 , SWI 指 令 可 被 有 条 件 地 执 行 。<br />

从 C/C++ 中 将 SWI 声 明 为 一 个 __SWI 函 数 并 调 用 它 。 例 如 :<br />

__swi(0) void my_swi(int);<br />

.<br />

.<br />

.<br />

my_swi(65);<br />

它 确 保 了 SWI 以 内 联 方 式 进 行 编 译 , 勿 需 额 外 的 调 用 开 销 , 其 条 件 是 :<br />

• 任 何 自 变 量 只 能 被 传 递 到 r0-r3 ;<br />

• 任 何 结 果 只 能 被 返 回 到 r0-r3。<br />

6-22 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


处 理 处 理 器 异 常<br />

其 参 数 被 传 递 到 了 SWI, 好 像 该 SWI 是 一 个 真 正 的 函 数 调 用 。 但 是 , 如 果 有 二<br />

到 四 个 返 回 值 , 则 必 须 告 诉 编 译 程 序 返 回 值 是 以 结 构 形 式 返 回 的 , 并 使 用<br />

__value_in_regs 命 令 。 这 是 因 为 基 于 结 构 值 的 函 数 通 常 被 处 理 为 一 个 void ( 空 )<br />

函 数 , 其 第 一 个 自 变 量 必 须 为 存 放 结 果 结 构 的 地 址 。<br />

示 例 6-10 和 示 例 6-11 展 示 了 提 供 SWI 编 号 0x0、0x1、0x2 和 0x3 的 SWI 处 理 程<br />

序 。SWI 0x0 和 0x1 每 一 个 都 占 用 二 个 整 型 参 数 并 返 回 一 个 单 一 结 果 。SWI 0x2 占<br />

用 四 个 参 数 并 返 回 一 个 单 一 结 果 。SWI 0x3 占 用 四 个 参 数 并 返 回 四 个 结 果 。 该 示<br />

例 位 于 Examples_directory\SWI\main.c 和 Examples_directory\SWI\swi.h。<br />

示 例 6-10 main.c<br />

#include <br />

#include "swi.h"<br />

unsigned *swi_vec = (unsigned *)0x08;<br />

extern void SWI_Handler(void);<br />

int main(void)<br />

{<br />

int result1, result2;<br />

struct four_results res_3;<br />

Install_Handler( (unsigned) SWI_Handler, swi_vec );<br />

printf("result1 = multiply_two(2,4) = %d\n", result1 = multiply_two(2,4));<br />

printf("result2 = multiply_two(3,6) = %d\n", result2 = multiply_two(3,6));<br />

printf("add_two( result1, result2 ) = %d\n", add_two( result1, result2 ));<br />

printf("add_multiply_two(2,4,3,6) = %d\n", add_multiply_two(2,4,3,6));<br />

res_3 = many_operations( 12, 4, 3, 1 );<br />

printf("res_3.a = %d\n", res_3.a );<br />

printf("res_3.b = %d\n", res_3.b );<br />

printf("res_3.c = %d\n", res_3.c );<br />

printf("res_3.d = %d\n", res_3.d );<br />

return 0;<br />

}<br />

示 例 6-11 swi.h<br />

__swi(0) int multiply_two(int, int);<br />

__swi(1) int add_two(int, int);<br />

__swi(2) int add_multiply_two(int, int, int, int);<br />

struct four_results<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 6-23


处 理 处 理 器 异 常<br />

{<br />

};<br />

int a;<br />

int b;<br />

int c;<br />

int d;<br />

__swi(3) __value_in_regs struct four_results<br />

many_operations(int, int, int, int);<br />

6.6.5 从 应 用 程 序 动 态 调 用 SWI<br />

在 某 些 情 形 下 , 需 要 调 用 直 到 运 行 时 才 会 知 道 其 编 号 的 SWI。 例 如 , 当 有 很 多 相<br />

关 操 作 可 在 同 一 目 标 上 执 行 , 并 且 每 一 个 操 作 都 有 其 自 己 的 SWI 时 , 就 会 发 生<br />

这 种 情 况 。 在 此 情 况 下 , 上 述 方 法 不 适 用 。<br />

有 几 种 解 决 方 法 , 例 如 , 可 以 通 过 :<br />

• 从 SWI 编 号 构 建 SWI 指 令 , 将 它 存 储 在 某 处 , 然 后 执 行 其 。<br />

• 使 用 通 用 的 SWI ( 作 为 一 个 额 外 的 自 变 量 ) 获 取 一 个 代 码 , 以 便 对 其 自 变<br />

量 执 行 实 际 操 作 。 该 通 用 SWI 对 操 作 进 行 解 码 并 予 以 执 行 。<br />

通 过 传 递 寄 存 器 ( 通 常 为 r0 或 r12) 中 所 需 要 的 操 作 数 , 用 汇 编 语 言 实 现 第 二<br />

种 机 制 。 这 样 就 可 重 新 编 写 SWI 处 理 程 序 , 对 相 应 寄 存 器 中 的 值 进 行 处 理 。 因<br />

为 有 些 值 必 须 以 注 释 字 段 传 递 到 SWI, 所 以 有 可 能 将 这 两 种 方 法 结 合 起 来 使 用 。<br />

例 如 , 操 作 系 统 可 能 会 使 用 单 一 的 一 条 SWI 指 令 并 用 寄 存 器 来 传 递 所 需 运 算 的 编<br />

号 。 这 使 得 其 它 SWI 空 间 可 用 于 特 定 应 用 程 序 的 SWI。 在 一 个 特 定 的 应 用 程 序<br />

中 , 如 果 从 指 令 中 提 取 SWI 编 号 的 开 销 太 大 , 就 可 使 用 这 个 方 法 。 <strong>ARM</strong><br />

(0x123456) 和 Thumb (0xAB) 半 主 机 方 式 的 SWI 就 是 这 样 实 现 的 。<br />

第 6-25 页 的 示 例 6-12 展 示 了 如 何 使 用 __swi 将 C 函 数 调 用 映 射 到 半 主 机 方 式 的<br />

SWI。 它 是 从 Examples_directory\embedded\embed\retarget.c 中 派 生 出 来 的 。<br />

6-24 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


处 理 处 理 器 异 常<br />

示 例 6-12 映 射 C 函 数 到 半 主 机 SWI<br />

#ifdef __thumb<br />

/* Thumb Semihosting SWI */<br />

#define SemiSWI 0xAB<br />

#else<br />

/* <strong>ARM</strong> Semihosting SWI */<br />

#define SemiSWI 0x123456<br />

#endif<br />

/* Semihosting SWI to write a character */<br />

__swi(SemiSWI) void Semihosting(unsigned op, char *c);<br />

#define WriteC(c) Semihosting (0x3,c)<br />

void write_a_character(int ch)<br />

{<br />

char tempch = ch;<br />

WriteC( &tempch );<br />

}<br />

编 译 程 序 含 有 一 个 机 制 , 用 以 支 持 使 用 r12 来 传 递 所 需 运 算 的 值 。 在 “<strong>ARM</strong> 过<br />

程 调 用 标 准 ” 下 ,r12 为 ip 寄 存 器 , 并 且 专 用 于 函 数 调 用 。 其 它 时 间 内 可 将 其 用<br />

作 暂 存 寄 存 器 。 通 用 SWI 的 自 变 量 被 传 递 到 r0-r3 寄 存 器 中 , 如 前 面 所 述 , 其 值<br />

被 有 选 择 地 返 回 到 r0-r3 中 。 传 递 到 r12 中 的 操 作 数 可 以 ( 但 不 要 求 ) 是 通 用<br />

SWI 调 用 的 SWI 编 号 。<br />

示 例 6-13 展 示 了 使 用 通 用 或 间 接 SWI 的 C 语 言 程 序 段 。<br />

示 例 6-13<br />

__swi_indirect(0x80)<br />

unsigned SWI_ManipulateObject(unsigned operationNumber,<br />

unsigned object,unsigned parameter);<br />

unsigned DoSelectedManipulation(unsigned object,<br />

unsigned parameter, unsigned operation)<br />

{ return SWI_ManipulateObject(operation, object, parameter);<br />

}<br />

它 生 成 了 以 下 代 码 :<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 6-25


处 理 处 理 器 异 常<br />

DoSelectedManipulation PROC<br />

STMFD sp!,{r3,lr}<br />

MOV r12,r2<br />

SWI 0x80<br />

LDMFD sp!,{r3,pc}<br />

ENDP<br />

还 可 利 用 __swi 机 制 从 C 中 将 SWI 编 号 传 递 到 r0 中 。 例 如 , 如 果 将 SWI 0x0 用 作<br />

通 用 SWI, 且 操 作 0 为 字 符 读 , 操 作 1 为 字 符 写 , 那 么 , 就 可 如 下 建 立 :<br />

__swi (0) char __ReadCharacter (unsigned op);<br />

__swi (0) void __WriteCharacter (unsigned op, char c);<br />

可 通 过 如 下 定 义 使 其 具 有 更 好 的 可 读 性 风 格 :<br />

#define ReadCharacter () __ReadCharacter (0);<br />

#define WriteCharacter (c) __WriteCharacter (1, c);<br />

但 是 , 如 果 以 这 种 方 式 使 用 的 r0, 那 么 , 仅 有 三 个 寄 存 器 可 用 于 将 参 数 传 递 到<br />

SWI。 通 常 , 在 不 得 不 将 除 r0-r3 之 外 的 更 多 参 数 传 递 给 子 例 程 时 , 可 通 过 使 用<br />

堆 来 完 成 但 是 , SWI 处 理 程 序 不 容 易 存 取 堆 参 数 , 因 为 通 常 它 们 是 存 在 用 户 模<br />

式 的 堆 里 而 不 是 在 SWI 处 理 程 序 使 用 的 超 级 用 户 模 式 的 堆 里 。<br />

作 为 另 一 种 选 择 , 其 中 一 个 寄 存 器 ( 通 常 是 r1) 可 用 来 指 向 存 储 其 它 参 数 的 存<br />

储 器 块 。<br />

6-26 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


处 理 处 理 器 异 常<br />

6.7 中 断 处 理 程 序<br />

<strong>ARM</strong> 处 理 器 有 FIQ 和 IRQ 两 级 外 部 中 断 , 均 是 由 低 (LOW) 电 平 信 号 激 活 进 入<br />

内 核 程 序 。 为 响 应 一 个 中 断 , CPSR 中 相 应 的 中 断 使 能 位 必 须 清 空 。<br />

在 以 下 方 式 中 , FIQ 较 IRQ 有 更 高 的 优 先 级 :<br />

• 当 发 生 多 个 中 断 时 , 首 先 处 理 FIQ。<br />

• 处 理 FIQ 造 成 禁 用 IRQ, 直 至 FIQ 处 理 程 序 再 次 将 其 置 为 可 用 状 态 前 禁 止<br />

使 用 。 这 通 常 是 通 过 在 处 理 程 序 结 束 时 将 CPSR 从 SPSR 中 恢 复 来 完 成 的 。<br />

FIQ 向 量 是 向 量 表 ( 在 地 址 0x1C 处 ) 最 后 的 入 口 , 使 得 FIQ 处 理 程 序 被 直 接 放<br />

置 在 该 向 量 位 置 并 从 该 地 址 顺 序 执 行 。 它 避 免 了 跳 转 以 及 相 关 的 延 迟 , 并 意 味 着<br />

如 果 系 统 有 缓 存 , 向 量 表 和 FIQ 处 理 程 序 必 须 被 锁 定 在 其 所 在 的 块 内 。 这 一 点<br />

非 常 重 要 , 因 为 FIQ 是 为 尽 快 处 理 中 断 而 设 计 的 。 五 个 额 外 的 FIQ 模 式 的 编 组<br />

寄 存 器 使 得 调 用 与 处 理 程 序 之 间 的 状 态 得 以 保 存 , 从 而 又 加 快 了 其 执 行 速 度 。<br />

备 注<br />

中 断 处 理 程 序 必 须 包 括 清 除 中 断 来 源 的 代 码 。<br />

6.7.1 C 语 言 编 写 的 简 单 中 断 处 理 程 序<br />

可 通 过 使 用 __irq 函 数 声 明 关 键 字 来 编 写 简 单 的 C 语 言 中 断 处 理 程 序 。 可 用<br />

__irq 关 键 字 来 编 写 简 单 单 级 中 断 处 理 程 序 , 以 及 调 用 子 例 程 的 中 断 处 理 程 序 。<br />

但 是 , 不 能 用 __irq 关 键 字 来 编 写 reentrant( 重 入 ) 中 断 处 理 程 序 , 因 它 对 SPSR<br />

不 进 行 存 储 或 恢 复 。 本 文 中 ,“ 重 入 ” 的 含 义 是 指 处 理 程 序 能 再 次 设 置 中 断 并 能<br />

将 其 自 身 中 断 。 有 关 详 细 信 息 请 参 阅 第 6-29 页 的 可 重 入 中 断 处 理 程 序 。<br />

__irq 关 键 字 :<br />

• 保 护 所 有 ATPCS 易 损 坏 的 寄 存 器 ;<br />

• 保 护 所 有 被 函 数 使 用 的 其 它 寄 存 器 ( 不 包 括 浮 点 寄 存 器 );<br />

• 通 过 将 程 序 计 数 器 设 置 到 (lr - 4) 并 恢 复 CPSR 的 初 始 数 据 值 来 退 出 函 数 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 6-27


处 理 处 理 器 异 常<br />

如 果 该 函 数 调 用 了 一 个 子 例 程 , __irq 除 保 护 其 它 易 损 坏 寄 存 器 外 , 还 为 中 断 模<br />

式 保 护 链 接 寄 存 器 。 有 关 详 细 信 息 请 参 阅 从 中 断 处 理 程 序 调 用 子 例 程 。<br />

备 注<br />

在 使 用 汇 编 Thumb C 代 码 时 , C 语 言 中 断 处 理 程 序 不 能 以 这 种 方 式 生 成 。 在<br />

Thumb 模 式 下 编 译 时 ,__irq 关 键 字 有 问 题 , 产 生 中 断 或 任 何 其 它 异 常 时 , 处 理<br />

器 总 是 转 到 <strong>ARM</strong> 状 态 。<br />

但 是 , 由 __irq 函 数 调 用 的 子 例 程 可 以 为 Thumb 进 行 编 译 ( 当 启 用 交 互 时 )。 有<br />

关 交 互 的 详 细 信 息 , 请 参 阅 第 4 章 <strong>ARM</strong> 和 Thumb 交 互 操 作 。<br />

从 中 断 处 理 程 序 调 用 子 例 程<br />

如 果 从 高 级 中 断 处 理 程 序 调 用 子 例 程 ,__irq 关 键 字 也 将 从 堆 中 恢 复 lr_IRQ 的<br />

值 , 以 便 它 能 被 SUBS 指 令 使 用 , 使 得 在 处 理 完 该 中 断 后 返 回 到 正 确 的 地 址 。<br />

示 例 6-14 说 明 了 这 一 实 现 过 程 。 高 层 中 断 处 理 程 序 在 0x80000000 基 地 址 读 取 存<br />

储 器 映 射 中 断 控 制 器 的 值 。 如 果 该 地 址 的 值 为 1, 高 层 处 理 程 序 跳 转 到 一 个 用 C<br />

语 言 编 写 的 处 理 程 序 。<br />

示 例 6-14<br />

__irq void IRQHandler (void)<br />

{<br />

volatile unsigned int *base = (unsigned int *) 0x80000000;<br />

}<br />

if (*base == 1)<br />

{<br />

C_int_handler();<br />

}<br />

*(base+1) = 0;<br />

// which interrupt was it?<br />

// process the interrupt<br />

// clear the interrupt<br />

用 armcc 编 译 , 示 例 6-14 生 成 以 下 代 码 :<br />

IRQHandler PROC<br />

STMFD<br />

MOV<br />

LDR<br />

SUB<br />

CMP<br />

sp!,{r0-r4,r12,lr}<br />

r4,#0x80000000<br />

r0,[r4,#0]<br />

sp,sp,#4<br />

r0,#1<br />

6-28 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


处 理 处 理 器 异 常<br />

BLEQ<br />

MOV<br />

STR<br />

ADD<br />

LDMFD<br />

SUBS<br />

ENDP<br />

C_int_handler<br />

r0,#0<br />

r0,[r4,#4]<br />

sp,sp,#4<br />

sp!,{r0-r4,r12,lr}<br />

pc,lr,#4<br />

将 其 与 没 有 使 用 __irq 关 键 字 时 的 结 果 比 较 :<br />

IRQHandler PROC<br />

STMFD<br />

MOV<br />

LDR<br />

CMP<br />

BLEQ<br />

MOV<br />

STR<br />

LDMFD<br />

ENDP<br />

sp!,{r4,lr}<br />

r4,#0x80000000<br />

r0,[r4,#0]<br />

r0,#1<br />

C_int_handler<br />

r0,#0<br />

r0,[r4,#4]<br />

sp!,{r4,pc}<br />

6.7.2 可 重 入 中 断 处 理 程 序<br />

如 果 中 断 处 理 程 序 再 次 激 活 了 中 断 , 然 后 调 用 一 个 子 例 程 , 并 且 产 生 了 另 个 一 中<br />

断 , 则 在 第 二 个 IRQ 被 占 用 时 , 子 例 程 的 返 回 地 址 ( 存 储 在 lr_IRQ 中 ) 将 被 破<br />

坏 。 在 C 语 言 中 使 用 __irq 关 键 字 不 会 造 成 重 入 中 断 处 理 程 序 所 要 求 的 对 SPSR<br />

进 行 存 储 和 恢 复 , 因 而 要 使 用 汇 编 语 言 编 写 高 层 中 断 处 理 程 序 。<br />

在 跳 转 到 嵌 套 子 例 程 或 C 函 数 前 , 重 入 中 断 处 理 程 序 须 保 存 IRQ 状 态 、 切 换 处<br />

理 器 模 式 并 为 新 的 处 理 器 模 式 保 存 该 状 态 。<br />

<strong>ARM</strong> 版 本 4 或 以 后 版 本 可 切 换 至 系 统 模 式 。 系 统 模 式 使 用 了 用 户 模 式 寄 存 器 ,<br />

并 启 用 您 的 异 常 处 理 程 序 所 要 求 的 特 权 存 取 方 式 。 有 关 详 细 信 息 请 参 阅 第 6-43<br />

页 的 系 统 模 式 。 相 反 , 在 早 于 v4 版 本 的 <strong>ARM</strong> 体 系 结 构 中 , 必 须 切 换 到 超 级 用<br />

户 模 式 。<br />

备 注<br />

该 方 法 适 用 于 IRQ 和 FIQ 中 断 。 但 是 , 因 FIQ 中 断 要 求 尽 快 得 到 服 务 , 通 常 仅<br />

有 一 个 中 断 源 , 所 以 , 可 能 不 必 为 其 提 供 重 入 特 性 。<br />

IRQ 处 理 程 序 安 全 地 激 活 中 断 所 需 的 步 骤 是 :<br />

1. 构 造 返 回 地 址 并 保 存 在 IRQ 堆 中 。<br />

2. 保 存 工 作 寄 存 器 和 spsr_IRQ。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 6-29


处 理 处 理 器 异 常<br />

3. 清 除 中 断 源 。<br />

4. 切 换 到 系 统 模 式 并 再 次 激 活 中 断 。<br />

5. 保 存 用 户 模 式 链 接 寄 存 器 和 非 被 调 用 函 数 存 储 的 寄 存 器 。<br />

6. 调 用 C 中 断 处 理 程 序 函 数 。<br />

7. C 中 断 处 理 程 序 返 回 时 , 恢 复 用 户 模 式 寄 存 器 并 禁 用 中 断 。<br />

8. 切 换 至 IRQ 模 式 , 禁 用 中 断 。<br />

9. 恢 复 工 作 寄 存 器 和 spsr_IRQ。<br />

10. 从 IRQ 返 回 。<br />

示 例 6-15 展 示 了 它 在 系 统 模 式 下 是 如 何 进 行 的 。 在 lr_IRQ 被 推 到 栈 顶 后 , 寄 存<br />

器 r12 和 r14 被 用 作 临 时 工 作 寄 存 器 。<br />

示 例 6-15<br />

AREA INTERRUPT, CODE, READONLY<br />

IMPORT C_irq_handler<br />

IRQ<br />

SUB lr, lr, #4 ; construct the return address<br />

STMFD sp!, {lr} ; and push the adjusted lr_IRQ<br />

MRS r14, SPSR ; copy spsr_IRQ to r14<br />

STMFD sp!, {r12, r14} ; save work regs and spsr_IRQ<br />

; Add instructions to clear the interrupt here<br />

; then re-enable interrupts.<br />

MSR CPSR_c, #0x1F ; switch to SYS mode, FIQ and IRQ<br />

; enabled. USR mode registers<br />

; are now current.<br />

STMFD sp!, {r0-r3, lr} ; save lr_USR and non-callee<br />

; saved registers<br />

BL C_irq_handler ; branch to C IRQ handler.<br />

LDMFD sp!, {r0-r3, lr} ; restore registers<br />

MSR CPSR_c, #0x92 ; switch to IRQ mode and disable<br />

; IRQs. FIQ is still enabled.<br />

LDMFD sp!, {r12, r14} ; restore work regs and spsr_IRQ<br />

MSR SPSR_cf, r14<br />

LDMFD sp!, {pc}^ ; return from IRQ.<br />

END<br />

本 例 假 设 FIQ 为 永 久 启 用 。<br />

6-30 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


处 理 处 理 器 异 常<br />

6.7.3 汇 编 语 言 编 写 的 中 断 处 理 程 序 示 例<br />

为 确 保 快 速 执 行 , 通 常 采 用 汇 编 语 言 来 编 写 中 断 处 理 程 序 。 以 下 章 节 给 出 了 几 个<br />

示 例 :<br />

• 单 通 道 DMA 传 送 ;<br />

• 第 6-32 页 的 双 通 道 DMA 传 送 ;<br />

• 第 6-33 页 的 中 断 的 优 先 化 ;<br />

• 第 6-35 页 的 上 下 文 切 换 。<br />

单 通 道 DMA 传 送<br />

示 例 6-16 展 示 了 一 个 中 断 处 理 程 序 , 其 执 行 从 I/O 到 存 储 器 传 送 ( 软 DMA) 中<br />

断 驱 动 。 该 代 码 是 一 个 FIQ 处 理 程 序 。 它 使 用 FIQ 编 组 寄 存 器 来 维 护 中 断 间 的<br />

状 态 。 该 代 码 最 适 合 位 于 0x1C。<br />

在 示 例 代 码 中 :<br />

r8 指 向 数 据 读 取 的 I/O 设 备 的 基 本 地 址 。<br />

IOData<br />

是 读 取 基 地 址 到 32 位 数 据 寄 存 器 的 偏 移 量 。 读 取 此 寄 存 器 清 除 该<br />

中 断 。<br />

r9 指 向 被 传 送 数 据 所 在 的 存 储 器 位 置 。<br />

r10 指 向 传 送 至 目 的 地 的 最 后 一 个 地 址 。<br />

处 理 正 常 传 送 的 全 部 序 列 为 四 个 指 令 。 位 于 有 条 件 返 回 语 句 后 的 代 码 被 用 作 传<br />

送 结 束 信 号 。<br />

示 例 6-16<br />

LDR r11, [r8, #IOData] ; Load port data from the IO<br />

; device.<br />

STR r11, [r9], #4 ; Store it to memory: update<br />

; the pointer.<br />

CMP r9, r10 ; Reached the end ?<br />

SUBLSS pc, lr, #4<br />

; No, so return.<br />

; Insert transfer complete<br />

; code here.<br />

可 通 过 使 用 载 入 字 节 指 令 替 换 载 入 指 令 来 实 现 字 节 传 送 。 从 存 储 器 到 一 个 I/O 设<br />

备 的 传 送 是 通 过 交 换 载 入 和 存 储 指 令 的 选 址 方 式 来 完 成 的 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 6-31


处 理 处 理 器 异 常<br />

双 通 道 DMA 传 送<br />

除 处 理 两 个 通 道 外 , 示 例 6-17 类 似 于 第 6-31 页 的 示 例 6-16。 该 代 码 是 一 个 FIQ<br />

处 理 程 序 。 它 使 用 FIQ 编 组 寄 存 器 来 维 护 中 断 间 的 状 态 。 该 代 码 最 适 合 位 于<br />

0x1c。<br />

在 示 例 代 码 中 :<br />

r8 指 向 读 取 数 据 的 I/O 设 备 的 基 本 地 址 。<br />

IOStat<br />

IOPort1Active<br />

是 从 基 本 地 址 到 寄 存 器 的 偏 移 量 , 指 示 两 个 端 口 中 的 哪 个 造<br />

成 了 中 断 。<br />

是 一 个 位 屏 蔽 , 指 示 是 否 是 第 一 个 端 口 造 成 了 中 断 ( 否 则 就<br />

假 设 第 二 个 接 口 造 成 了 中 断 )。<br />

IOPort1, IOPort2 是 要 读 取 的 寄 存 器 的 偏 移 量 。 读 取 一 个 数 据 寄 存 器 清 除 了 相<br />

应 端 口 的 中 断 。<br />

r9 指 向 从 第 一 个 端 口 传 送 数 据 到 该 存 储 器 的 位 置 。<br />

r10 指 向 从 第 二 个 端 口 传 送 数 据 到 该 存 储 器 的 位 置 。<br />

r11, r12 指 向 传 送 目 的 地 的 最 后 一 个 地 址 (r11 用 于 第 一 个 端 口 ,r12<br />

用 于 第 二 个 端 口 )。<br />

处 理 正 常 传 送 的 全 部 序 列 为 九 个 指 令 。 位 于 有 条 件 返 回 语 句 后 的 代 码 被 用 作 传<br />

送 结 束 信 号 。<br />

示 例 6-17<br />

LDR r13, [r8, #IOStat] ; Load status register to find which port<br />

; caused the interrupt.<br />

TST r13, #IOPort1Active<br />

LDREQ r13, [r8, #IOPort1] ; Load port 1 data.<br />

LDRNE r13, [r8, #IOPort2] ; Load port 2 data.<br />

STREQ r13, [r9], #4 ; Store to buffer 1.<br />

STRNE r13, [r10], #4 ; Store to buffer 2.<br />

CMP r9, r11 ; Reached the end?<br />

CMPLE r10, r12 ; On either channel?<br />

SUBNES pc, lr, #4<br />

; Return<br />

; Insert transfer complete code here.<br />

6-32 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


处 理 处 理 器 异 常<br />

可 通 过 使 用 载 入 字 节 指 令 替 换 载 入 指 令 来 实 现 字 节 传 送 。 从 存 储 器 到 I/O 设 备 的<br />

传 送 是 通 过 交 换 条 件 载 入 和 条 件 存 储 指 令 的 选 址 方 式 来 完 成 的 。<br />

中 断 的 优 先 化<br />

示 例 6-18 为 高 达 32 个 的 中 断 源 分 派 了 其 相 应 的 处 理 程 序 例 程 。 由 于 它 是 为 使 用<br />

正 常 中 断 向 量 (IRQ) 而 设 计 的 , 所 以 从 位 置 0x18 跳 转 。<br />

由 外 设 模 块 来 对 中 断 进 行 优 先 级 处 理 , 并 在 I/O 寄 存 器 中 提 供 当 前 的 有 效 高 优 先<br />

级 中 断 。<br />

在 示 例 代 码 中 :<br />

IntBase 存 储 中 断 控 制 器 的 基 本 地 址 。<br />

IntLevel 存 储 包 含 现 行 中 断 高 度 优 先 级 的 寄 存 器 的 偏 移 量 。<br />

r13 假 设 指 向 一 个 小 而 完 全 递 减 的 堆 。<br />

十 条 指 令 后 ( 包 括 跳 转 到 本 代 码 的 那 条 指 令 ) 重 新 开 启 了 中 断 。<br />

再 经 过 两 条 指 令 进 入 了 每 个 中 断 的 特 定 处 理 程 序 ( 所 有 寄 存 器 均 存 储 在 堆 中 )。<br />

此 外 , 每 个 处 理 程 序 的 最 后 三 条 指 令 在 再 次 关 闭 中 断 的 情 况 下 执 行 , 因 而 可 以 保<br />

证 从 堆 中 安 全 地 恢 复 SPSR。<br />

备 注<br />

Application Note 30: 软 件 中 断 的 优 先 化 介 绍 了 使 用 软 件 进 行 多 个 中 断 源 的 优 先<br />

化 , 与 此 处 所 述 的 用 硬 件 进 行 的 优 先 化 相 反 。<br />

示 例 6-18<br />

; first save the critical state<br />

SUB lr, lr, #4 ; Adjust the return address<br />

; before we save it.<br />

STMFD sp!, {lr} ; Stack return address<br />

MRS r14, SPSR ; get the SPSR ...<br />

STMFD sp!, {r12, r14} ; ... and stack that plus a<br />

; working register too.<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 6-33


处 理 处 理 器 异 常<br />

; Now get the priority level of the<br />

; highest priority active interrupt.<br />

MOV r12, #IntBase ; Get the interrupt controller's<br />

; base address.<br />

LDR r12, [r12, #IntLevel] ; Get the interrupt level (0 to 31).<br />

; Now read-modify-write the CPSR to enable interrupts.<br />

MRS r14, CPSR ; Read the status register.<br />

BIC r14, r14, #0x80 ; Clear the I bit<br />

; (use 0x40 for the F bit).<br />

MSR CPSR_c, r14 ; Write it back to re-enable<br />

; interrupts and<br />

LDR pc, [pc, r12, LSL #2] ; jump to the correct handler.<br />

; PC base address points to this<br />

; instruction + 8<br />

NOP<br />

; pad so the PC indexes this table.<br />

; Table of handler start addresses<br />

DCD Priority0Handler<br />

DCD Priority1Handler<br />

DCD Priority2Handler<br />

; ...<br />

Priority0Handler<br />

STMFD sp!, {r0 - r11} ; Save other working registers.<br />

; Insert handler code here.<br />

; ...<br />

LDMFD sp!, {r0 - r11} ; Restore working registers (not r12).<br />

; Now read-modify-write the CPSR to disable interrupts.<br />

MRS r12, CPSR ; Read the status register.<br />

ORR r12, r12, #0x80 ; Set the I bit<br />

; (use 0x40 for the F bit).<br />

MSR CPSR_c, r12 ; Write it back to disable interrupts.<br />

; Now that interrupt disabled, can safely restore SPSR then return.<br />

LDMFD sp!, {r12, r14} ; Restore r12 and get SPSR.<br />

MSR SPSR_csxf, r14 ; Restore status register from r14.<br />

LDMFD sp!, {pc}^ ; Return from handler.<br />

Priority1Handler<br />

; ...<br />

6-34 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


处 理 处 理 器 异 常<br />

上 下 文 切 换<br />

第 6-35 页 的 示 例 6-19 实 现 了 在 用 户 模 式 下 的 环 境 切 换 。 其 代 码 是 基 于 指 向 它 要<br />

运 行 的 过 程 的 过 程 控 制 块 (PCBs) 指 针 列 表 。<br />

图 6-5 展 示 了 示 例 所 期 望 的 PCB 布 局 。<br />

图 6-5 PCB 布 局<br />

指 向 下 一 个 要 运 行 的 过 程 的 PCB 指 针 是 由 r12 完 成 的 , 且 该 项 列 表 末 尾 有 一 零<br />

指 针 。r13 寄 存 器 是 指 向 PCB 的 指 针 , 并 在 一 小 段 时 间 间 隔 被 保 存 , 因 而 , 进 入<br />

时 它 指 向 现 行 运 行 过 程 的 PCB。<br />

示 例 6-19<br />

STMIA r13, {r0 - r14}^ ; Dump user registers above r13.<br />

MRS r0, SPSR ; Pick up the user status<br />

STMDB r13, {r0, lr} ; and dump with return address below.<br />

LDR r13, [r12], #4 ; Load next process info pointer.<br />

CMP r13, #0 ; If it is zero, it is invalid<br />

LDMNEDB r13, {r0, lr}<br />

; Pick up status and return address.<br />

MSRNE SPSR_cxsf, r0 ; Restore the status.<br />

LDMNEIA r13, {r0 - r14}^ ; Get the rest of the registers<br />

NOP<br />

SUBNES pc, lr, #4<br />

; and return and restore CPSR.<br />

; Insert "no next process code" here.<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 6-35


处 理 处 理 器 异 常<br />

6.8 复 位 处 理 程 序<br />

复 位 处 理 程 序 实 施 的 操 作 取 决 于 所 开 发 软 件 的 运 行 系 统 。 例 如 , 可 以 是 :<br />

• 设 置 异 常 向 量 。 详 细 信 息 请 参 阅 第 6-13 页 的 安 装 异 常 处 理 程 序 。<br />

• 初 始 化 堆 和 寄 存 器 。<br />

• 如 果 使 用 MMU, 初 始 化 存 储 器 系 统 。<br />

• 初 始 化 任 何 关 键 I/O 设 备 。<br />

• 激 活 中 断 。<br />

• 改 变 处 理 器 模 式 和 / 或 状 态 。<br />

• 初 始 化 C 语 言 和 调 用 主 应 用 程 序 所 需 的 变 量 。<br />

有 关 详 细 信 息 请 参 阅 第 2 章 嵌 入 式 软 件 开 发 。<br />

6-36 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


处 理 处 理 器 异 常<br />

6.9 未 定 义 的 指 令 处 理 程 序<br />

提 供 处 理 器 不 能 识 别 的 指 令 给 系 统 所 配 的 协 处 理 器 。 如 果 该 指 令 仍 不 能 被 识 别 ,<br />

就 产 生 了 未 定 义 指 令 异 常 。 可 能 的 情 形 是 , 该 指 令 为 协 处 理 器 所 建 , 但 相 关 的 协<br />

处 理 器 ( 如 浮 点 加 速 器 ) 没 有 配 到 系 统 上 。 但 是 , 可 能 会 有 一 个 软 件 模 拟 程 序<br />

来 替 代 该 协 处 理 器 。<br />

这 样 的 模 拟 程 序 必 须 :<br />

1. 将 其 分 配 到 未 定 义 指 令 向 量 并 存 储 旧 的 内 容 。<br />

2. 检 查 该 未 定 义 指 令 确 定 其 是 否 必 须 进 行 模 拟 。 这 与 SWI 处 理 程 序 提 取 SWI<br />

编 号 类 似 , 但 模 拟 程 序 不 是 提 取 底 部 的 24 位 , 而 是 提 取 27-24 位 。<br />

这 些 位 按 如 下 方 式 决 定 指 令 是 否 为 协 处 理 器 操 作 :<br />

• 如 果 27 到 24 位 = b1110 或 b110x, 该 指 令 即 为 协 处 理 器 指 令 。<br />

• 如 果 8-11 位 显 示 该 协 处 理 器 模 拟 程 序 须 处 理 该 项 指 令 , 则 模 拟 程 序<br />

必 须 处 理 该 指 令 并 返 回 用 户 程 序 。<br />

3. 否 则 , 模 拟 程 序 必 须 通 过 使 用 模 拟 程 序 安 装 时 存 储 的 向 量 , 将 该 异 常 传 递<br />

到 其 原 始 处 理 程 序 ( 或 链 表 中 的 下 一 个 模 拟 程 序 )。<br />

链 表 上 的 模 拟 程 序 用 完 时 , 不 再 处 理 指 令 , 因 而 , 未 定 义 指 令 处 理 程 序 必 须 报 告<br />

出 错 并 退 出 。 有 关 详 细 信 息 请 参 阅 第 6-41 页 的 链 结 异 常 处 理 程 序 。<br />

备 注<br />

Thumb 指 令 集 没 有 协 处 理 器 指 令 , 因 此 不 要 求 未 定 义 指 令 处 理 程 序 模 拟 这 类<br />

指 令 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 6-37


处 理 处 理 器 异 常<br />

6.10 预 取 中 断 处 理 程 序<br />

如 果 系 统 中 没 有 MMU, 预 取 中 断 处 理 程 序 可 报 告 出 错 并 退 出 。 否 则 , 造 成 中 断 的<br />

地 址 必 须 存 储 在 物 理 存 储 器 中 。lr_ABT 指 向 造 成 中 断 的 下 一 条 指 令 的 地 址 , 因 此 ,<br />

该 地 址 被 存 储 在 lr_ABT - 4。 虚 拟 存 储 器 报 告 该 地 址 出 错 就 会 得 到 处 理 , 并 再 次 进<br />

行 取 指 令 操 作 。 处 理 程 序 返 回 同 一 个 指 令 而 不 是 它 下 面 的 那 个 指 令 , 例 如 :<br />

SUBS<br />

pc,lr,#4<br />

6-38 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


处 理 处 理 器 异 常<br />

6.11 数 据 中 断 处 理 程 序<br />

如 果 没 有 MMU, 数 据 中 断 处 理 程 序 必 须 报 告 出 错 并 退 出 。 如 果 有 MMU, 处 理<br />

程 序 必 须 处 理 虚 拟 存 储 器 错 误 。<br />

造 成 中 断 的 指 令 是 在 lr_ABT - 8, 因 为 lr_ABT 指 向 造 成 中 断 指 令 的 下 面 两 个 指 令 。<br />

以 下 类 型 的 指 令 均 可 造 成 该 中 断 :<br />

单 一 寄 存 器 载 入 或 存 储 (LDR 或 STR)<br />

反 应 取 决 于 处 理 器 类 型 :<br />

• 如 果 中 断 发 生 在 以 <strong>ARM</strong>6 为 基 础 的 处 理 器 :<br />

— 如 果 处 理 器 是 在 早 期 中 断 模 式 并 且 要 求 回 写 , 则 不 刷 新<br />

地 址 寄 存 器 。<br />

— 如 果 处 理 器 是 在 晚 期 中 断 模 式 并 且 要 求 回 写 , 则 刷 新 地<br />

址 寄 存 器 其 刷 新 一 定 是 未 完 成 。<br />

• 如 果 中 断 产 生 在 以 <strong>ARM</strong>7 为 基 础 的 处 理 器 , 包 括 <strong>ARM</strong>7TDMI,<br />

则 刷 新 地 址 寄 存 器 , 并 刷 新 一 定 是 未 完 成 。<br />

• 如 果 中 断 是 发 生 在 基 于 <strong>ARM</strong>9 、<strong>ARM</strong>10 或 Strong<strong>ARM</strong> 的 处<br />

理 器 , 该 地 址 被 处 理 器 恢 复 到 该 指 令 开 始 前 的 值 。 不 必 进 行 进<br />

一 步 的 恢 复 操 作 。<br />

交 换 (SWP) 该 指 令 不 涉 及 地 址 寄 存 器 刷 新 。<br />

载 入 多 个 或 存 储 多 个 (LDM 或 STM)<br />

反 应 取 决 于 处 理 器 类 型 :<br />

• 如 果 中 断 产 生 在 基 于 <strong>ARM</strong>6 或 <strong>ARM</strong>7 的 处 理 器 , 启 用 回 写 ,<br />

刷 新 基 址 寄 存 器 , 就 好 像 产 生 了 完 整 的 传 送 。<br />

在 寄 存 器 列 表 中 存 在 含 有 基 址 寄 存 器 的 LDM 情 况 下 , 处 理 器 以<br />

修 改 了 的 基 值 来 替 换 该 覆 盖 值 , 以 便 能 够 恢 复 。 可 以 使 用 所 涉<br />

及 到 的 寄 存 器 编 号 重 新 计 算 初 始 基 值 。<br />

• 如 果 中 断 产 生 在 基 于 <strong>ARM</strong>9 或 <strong>ARM</strong>10 的 处 理 器 且 启 用 回 写 ,<br />

该 基 址 寄 存 器 则 被 恢 复 到 该 指 令 开 始 前 它 所 保 存 的 值 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 6-39


处 理 处 理 器 异 常<br />

上 述 三 个 例 子 中 ,MMU 均 可 将 所 需 的 虚 拟 存 储 器 装 入 物 理 存 储 器 。MMU 故 障<br />

地 址 寄 存 器 (FAR) 包 含 造 成 该 中 断 的 地 址 。 完 成 后 , 处 理 程 序 可 返 回 并 尝 试 再 次<br />

执 行 该 指 令 。<br />

可 在 Examples_directory\databort 找 到 数 据 中 断 处 理 程 序 代 码 的 示 例 。<br />

6-40 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


处 理 处 理 器 异 常<br />

6.12 链 结 异 常 处 理 程 序<br />

某 些 情 况 下 , 一 个 特 定 的 异 常 可 能 会 有 几 个 不 同 的 源 。 例 如 :<br />

• Angel 使 用 一 条 未 定 义 指 令 来 执 行 断 点 。 但 是 , 当 该 协 处 理 器 不 存 在 时 执<br />

行 协 处 理 器 指 令 也 会 发 生 未 定 义 指 令 异 常 。<br />

• Angel 使 用 一 个 多 用 途 的 SWI, 例 如 从 用 户 模 式 进 入 超 级 用 户 模 式 , 并 支 持<br />

开 发 过 程 中 的 半 主 机 申 请 。 但 是 , RTOS 或 应 用 程 序 也 可 能 会 执 行 一 些<br />

SWI。<br />

在 此 情 况 下 , 可 采 用 下 列 方 法 扩 展 该 异 常 处 理 代 码 。<br />

• 单 层 扩 展 处 理 程 序 ;<br />

• 几 个 链 结 的 处 理 程 序 。<br />

6.12.1 单 层 扩 展 处 理 程 序<br />

某 些 情 况 下 , 将 异 常 处 理 程 序 的 代 码 加 以 扩 展 来 确 定 产 生 异 常 的 源 是 可 能 的 , 然<br />

后 直 接 调 用 相 应 代 码 。 这 种 情 况 下 , 需 要 为 异 常 处 理 程 序 修 改 代 码 。<br />

Angel 是 为 简 化 该 方 法 而 编 写 。 Angel 将 SWI 和 未 定 义 指 令 进 行 解 码 , 并 且<br />

Angel 异 常 处 理 程 序 可 进 行 扩 展 来 处 理 非 Angel SWI 和 未 定 义 指 令 。<br />

但 是 , 该 方 法 仅 在 编 写 单 层 异 常 处 理 程 序 时 所 有 的 异 常 源 均 为 已 知 的 情 况 下 才<br />

是 有 用 的 。<br />

6.12.2 几 个 链 结 的 处 理 程 序<br />

某 些 情 况 下 不 仅 仅 要 求 单 层 处 理 程 序 。 在 标 准 Angel 调 试 器 执 行 的 情 况 下 , 下<br />

载 了 某 个 想 支 持 其 它 SWI 的 独 立 用 户 应 用 程 序 ( 或 RTOS)。 新 载 入 的 应 用 程<br />

序 可 能 会 有 其 完 全 独 立 的 异 常 处 理 程 序 要 求 进 行 安 装 , 但 它 不 能 取 代 Angel 处<br />

理 程 序 。<br />

在 此 情 况 下 , 当 新 处 理 程 序 发 现 异 常 源 不 是 它 能 处 理 的 源 时 , 则 必 须 标 记 原 有 的<br />

处 理 程 序 的 地 址 、 以 便 该 新 处 理 程 序 能 够 调 用 原 有 的 处 理 程 序 。 例 如 , 在 发 现 某<br />

个 SWI 不 是 RTOS SWI 时 , RTOS SWI 处 理 程 序 调 用 Angel SWI 处 理 程 序 , 使<br />

得 该 Angel SWI 处 理 程 序 有 机 会 处 理 它 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 6-41


处 理 处 理 器 异 常<br />

该 方 法 可 扩 展 到 任 何 多 个 级 , 以 建 立 一 个 处 理 程 序 链 。 虽 然 采 用 该 方 法 的 代 码 能<br />

使 每 一 处 理 程 序 完 全 独 立 , 但 是 , 它 比 采 用 单 层 处 理 程 序 的 效 率 要 低 , 或 至 少 它<br />

在 处 理 程 序 链 上 走 得 越 深 , 其 效 率 就 会 越 低 。<br />

第 6-15 页 的 从 C 安 装 处 理 程 序 中 给 出 的 两 个 例 程 都 返 回 原 有 的 向 量 内 容 。 可 将<br />

其 解 码 以 便 将 其 赋 予 :<br />

跳 转 指 令 的 偏 移 量<br />

可 利 用 其 计 算 初 始 处 理 程 序 的 位 置 , 使 其 激 活 一 个 新 的 跳 转 指 令 ,<br />

构 建 该 指 令 并 将 其 存 储 在 存 储 器 中 的 合 适 地 点 。 如 果 替 换 的 处 理 程<br />

序 无 法 处 理 该 异 常 , 它 可 跳 转 到 所 构 建 的 转 移 指 令 然 后 再 跳 转 到 原<br />

先 的 处 理 程 序 。<br />

用 来 存 储 原 先 的 处 理 程 序 地 址 的 位 置<br />

如 果 应 用 程 序 的 处 理 程 序 无 法 处 理 该 异 常 , 必 须 从 该 位 置 载 入 程 序<br />

计 数 器 。<br />

多 数 情 况 下 , 不 必 进 行 这 样 的 计 算 , 因 为 调 试 监 督 程 序 或 RTOS 处 理 程 序 的 信<br />

息 可 供 您 使 用 。 如 果 是 这 样 , 要 求 链 入 下 一 个 处 理 程 序 的 指 令 可 被 硬 性 编 码 到<br />

该 应 用 程 序 中 。 处 理 程 序 的 最 后 一 部 分 必 须 检 查 所 处 理 的 异 常 产 生 原 因 。 如 检<br />

查 到 , 处 理 程 序 可 返 回 到 该 应 用 程 序 。 如 没 有 检 查 到 , 则 必 须 调 用 链 上 的 下 一<br />

个 处 理 程 序 。<br />

备 注<br />

在 调 试 监 督 处 理 程 序 之 前 链 结 一 个 处 理 程 序 , 从 系 统 中 清 除 该 监 督 程 序 时 必 须<br />

清 除 该 链 , 然 后 直 接 安 装 应 用 程 序 的 处 理 程 序 。<br />

6-42 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


处 理 处 理 器 异 常<br />

6.13 系 统 模 式<br />

<strong>ARM</strong> 体 系 结 构 定 义 了 一 个 用 户 模 式 , 该 模 式 有 15 个 通 用 寄 存 器 、 一 个 PC 和 一<br />

个 CPSR。 除 该 模 式 外 , 还 有 五 个 处 理 器 特 权 模 式 , 每 个 模 式 都 有 一 个 SPSR 和<br />

许 多 寄 存 器 , 以 便 替 换 用 户 模 式 下 15 个 通 用 寄 存 器 中 的 部 分 寄 存 器 。<br />

备 注<br />

本 节 内 容 仅 适 用 于 <strong>ARM</strong> 体 系 结 构 的 版 本 v4、 v4T 和 更 新 的 版 本 。<br />

发 生 处 理 器 异 常 时 , 当 前 程 序 计 数 器 被 复 制 到 异 常 模 式 的 链 寄 存 器 中 ,CPSR 被<br />

复 制 到 该 异 常 模 式 的 SPSR 中 。 然 后 , CPSR 以 与 异 常 相 关 的 方 式 被 改 变 , 程 序<br />

计 数 器 被 设 置 到 一 个 异 常 定 义 的 地 址 , 开 始 执 行 异 常 处 理 程 序 。<br />

改 变 程 序 计 算 器 前 ,<strong>ARM</strong> 子 例 程 调 用 指 令 (BL) 将 返 回 地 址 复 制 到 r14 中 , 因 而 ,<br />

子 例 程 返 回 指 令 将 r14 移 动 到 PC (MOV pc,lr)。<br />

所 有 这 些 动 作 说 明 , 处 理 异 常 的 <strong>ARM</strong> 模 式 必 须 确 保 如 果 其 调 用 子 例 程 , 不 会 产<br />

生 另 一 个 同 类 型 的 异 常 , 因 为 该 子 例 程 的 返 回 地 址 被 异 常 的 返 回 地 址 所 覆 盖 。<br />

( 在 早 期 版 本 的 <strong>ARM</strong> 体 系 结 构 中 , 解 决 这 个 问 题 的 方 法 是 尽 量 避 免 在 异 常 模 式<br />

下 进 行 子 例 程 调 用 或 避 免 从 特 权 模 式 改 为 用 户 模 式 。 第 一 个 解 决 方 法 限 制 太 大 ,<br />

第 二 个 则 说 明 可 能 不 允 许 任 务 具 有 其 正 确 运 行 所 要 的 特 权 存 取 )。<br />

<strong>ARM</strong> 体 系 结 构 版 本 v4 和 更 新 版 本 提 供 了 一 个 被 称 为 system( 系 统 ) 模 式 的 处<br />

理 器 模 式 来 克 服 这 个 问 题 。 系 统 模 式 是 一 个 有 特 权 的 处 理 器 模 式 , 该 模 式 共 享<br />

用 户 模 式 的 寄 存 器 。 可 在 该 模 式 下 运 行 特 权 模 式 任 务 , 且 异 常 不 再 覆 盖 链 接 寄<br />

存 器 。<br />

备 注<br />

异 常 不 能 进 入 系 统 模 式 。 异 常 处 理 程 序 修 改 CPSR 以 便 进 入 系 统 模 式 。 请 参 阅 第<br />

6-29 页 的 可 重 入 中 断 处 理 程 序 的 一 个 示 例 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 6-43


处 理 处 理 器 异 常<br />

6-44 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


第 7 章<br />

调 试 通 信 通 道<br />

本 章 解 释 如 何 使 用 调 试 通 信 通 道 (DCC)。 其 中 包 含 下 列 各 部 分 :<br />

• 第 7-2 页 的 关 于 调 试 通 信 通 道 ;<br />

• 第 7-3 页 的 目 标 数 据 传 送 ;<br />

• 第 7-4 页 的 轮 询 调 试 通 信 ;<br />

• 第 7-8 页 的 中 断 驱 动 调 试 通 信 ;<br />

• 第 7-9 页 的 从 Thumb 状 态 访 问 ;<br />

• 第 7-10 页 的 半 主 机 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 7-1


调 试 通 信 通 道<br />

7.1 关 于 调 试 通 信 通 道<br />

<strong>ARM</strong> 内 核 ( 如 <strong>ARM</strong>7TDMI 和 <strong>ARM</strong>9TDMI ® ) 中 的 EmbeddedICE 逻 辑 单 元 包 含<br />

调 试 通 信 通 道 。 它 允 许 使 用 JTAG 端 口 和 协 议 转 换 器 ( 如 Multi-ICE ® ) 在 目 标 和<br />

主 机 调 试 器 之 间 传 递 数 据 , 无 需 停 止 程 序 流 程 或 进 入 调 试 状 态 。 本 章 描 述 目 标<br />

上 运 行 的 程 序 和 主 机 调 试 器 如 何 访 问 调 试 通 信 通 道 。<br />

RVCT 通 过 Multi-ICE 半 主 机 提 供 对 调 试 通 信 通 道 的 访 问 。<br />

7-2 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


调 试 通 信 通 道<br />

7.2 目 标 数 据 传 送<br />

目 标 使 用 <strong>ARM</strong> 指 令 MCR 和 MRC 将 调 试 通 信 通 道 作 为 <strong>ARM</strong> 内 核 上 的 协 处 理 器 14<br />

进 行 访 问 。<br />

提 供 了 两 个 寄 存 器 用 于 传 送 数 据 :<br />

通 信 数 据 读 取 寄 存 器<br />

一 个 32 位 宽 寄 存 器 , 用 于 接 收 来 自 调 试 器 的 数 据 。 以 下 指 令 在 Rd<br />

中 返 回 读 取 寄 存 器 的 值 :<br />

MRC p14, 0, Rd, c1, c0<br />

通 信 数 据 写 入 寄 存 器<br />

一 个 32 位 宽 寄 存 器 , 用 于 向 调 试 器 发 送 数 据 。 以 下 指 令 将 Rn 值 写<br />

到 写 入 寄 存 器 :<br />

MCR p14, 0, Rn, c1, c0<br />

备 注<br />

有 关 访 问 <strong>ARM</strong> 10 内 核 DCC 寄 存 器 的 信 息 , 请 参 阅 <strong>ARM</strong>10 Technical Reference<br />

Manual。 在 <strong>ARM</strong>9 之 后 的 处 理 器 中 , 所 用 指 令 、 状 态 位 位 置 以 及 状 态 位 解 释 都<br />

有 所 不 同 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 7-3


调 试 通 信 通 道<br />

7.3 轮 询 调 试 通 信<br />

在 通 信 数 据 读 取 和 写 入 寄 存 器 之 外 , 调 试 通 信 通 道 提 供 了 通 信 数 据 控 制 寄 存 器 。<br />

以 下 指 令 在 Rd 中 返 回 控 制 寄 存 器 值 :<br />

MRC p14, 0, Rd, c0, c0<br />

控 制 寄 存 器 中 的 两 个 位 提 供 目 标 和 主 机 调 试 器 之 间 的 同 步 握 手 :<br />

位 1 (W 位 ) 表 示 通 信 数 据 写 入 寄 存 器 是 否 空 闲 ( 从 目 标 的 角 度 ):<br />

W = 0 目 标 应 用 程 序 可 以 写 入 新 数 据 。<br />

W = 1 主 机 调 试 器 可 以 从 写 入 寄 存 器 中 扫 描 出 新 数 据 。<br />

位 0 (R 位 ) 表 示 通 信 数 据 读 取 寄 存 器 中 是 否 有 新 数 据 ( 从 目 标 的 角 度 ):<br />

R = 1 有 新 数 据 , 目 标 应 用 程 序 可 以 读 取 。<br />

R = 0 主 机 调 试 器 可 以 将 新 数 据 扫 描 到 读 取 寄 存 器 中 。<br />

备 注<br />

调 试 器 不 能 用 协 处 理 器 14 直 接 访 问 调 试 通 信 通 道 , 因 为 这 对 调 试 器 无 意 义 。 但<br />

是 , 调 试 器 可 以 使 用 扫 描 链 读 写 调 试 通 信 通 道 寄 存 器 。 调 试 通 信 通 道 数 据 和 控<br />

制 寄 存 器 映 射 到 EmbeddedICE 逻 辑 单 元 中 的 地 址 , 请 参 阅 查 看 EmbeddedICE 逻<br />

辑 寄 存 器 。<br />

7.3.1 查 看 EmbeddedICE 逻 辑 寄 存 器<br />

要 查 看 EmbeddedICE 逻 辑 寄 存 器 , 请 参 阅 Multi-ICE 2.2 版 用 户 指 南 或 更 新 版 本 。<br />

7-4 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


调 试 通 信 通 道<br />

7.3.2 目 标 到 调 试 器 的 通 信<br />

这 是 用 于 <strong>ARM</strong> 内 核 上 运 行 的 应 用 程 序 与 主 机 上 运 行 的 调 试 器 进 行 通 信 的 一 系<br />

列 事 件 :<br />

1. 目 标 应 用 程 序 检 查 调 试 通 信 通 道 写 入 寄 存 器 是 否 空 闲 可 用 。 为 此 , 它 使 用<br />

MRC 指 令 读 取 调 试 通 信 通 道 控 制 寄 存 器 , 以 检 查 W 位 是 否 已 清 除 。<br />

2. 如 果 W 位 已 清 除 , 则 调 试 通 信 写 入 寄 存 器 是 已 清 除 的 , 而 应 用 程 序 对 协 处<br />

理 器 14 使 用 MCR 指 令 将 字 写 入 寄 存 器 。 写 入 寄 存 器 操 作 自 动 设 置 W 位 。 如<br />

果 已 设 置 W 位 , 则 调 试 器 还 没 有 清 空 调 试 通 信 写 入 寄 存 器 。 如 果 应 用 程 序<br />

需 要 发 送 另 一 个 字 , 它 必 须 轮 询 W 位 , 直 到 它 已 清 除 。<br />

3. 调 试 器 通 过 扫 描 链 2 轮 询 调 试 通 信 控 制 寄 存 器 。 如 果 调 试 器 看 到 W 位 已 设<br />

置 , 则 它 可 以 读 调 试 通 信 通 道 数 据 寄 存 器 , 以 读 取 应 用 程 序 发 送 的 消 息 。<br />

读 取 数 据 进 程 自 动 清 除 调 试 通 信 控 制 寄 存 器 中 的 W 位 。<br />

示 例 7-1 说 明 了 这 一 实 现 过 程 。 示 例 代 码 可 以 在<br />

Examples_directory\dcc\outchan.s 中 得 到 。<br />

示 例 7-1<br />

AREA OutChannel, CODE, READONLY<br />

ENTRY<br />

MOV r1,#3 ; Number of words to send<br />

ADR r2, outdata ; Address of data to send<br />

pollout<br />

MRC p14,0,r0,c0,c0 ; Read control register<br />

TST r0, #2<br />

BNE pollout ; if W set, register still full<br />

write<br />

LDR r3,[r2],#4 ; Read word from outdata<br />

; into r3 and update the pointer<br />

MCR p14,0,r3,c1,c0 ; Write word from r3<br />

SUBS r1,r1,#1 ; Update counter<br />

BNE pollout ; Loop if more words to be written<br />

MOV r0, #0x18 ; Angel_SWIreason_ReportException<br />

LDR r1, =0x20026 ; ADP_Stopped_ApplicationExit<br />

SWI 0x123456 ; <strong>ARM</strong> semihosting SWI<br />

outdata<br />

DCB "Hello there!"<br />

END<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 7-5


调 试 通 信 通 道<br />

要 执 行 此 示 例 :<br />

1. 汇 编 outchan.s:<br />

armasm -g outchan.s<br />

2. 链 接 输 出 对 象 :<br />

armlink outchan.o -o outchan.axf<br />

链 接 步 骤 创 建 可 执 行 文 件 outchan.axf<br />

3. 载 入 并 执 行 该 映 像 。 详 细 信 息 请 参 阅 所 用 调 试 程 序 的 文 档 。<br />

7.3.3 调 试 器 到 目 标 的 通 信<br />

这 是 用 于 从 主 机 上 运 行 的 调 试 器 向 内 核 上 运 行 的 应 用 程 序 进 行 消 息 传 递 的 一 系<br />

列 事 件 :<br />

1. 调 试 器 轮 询 调 试 通 信 控 制 寄 存 器 的 R 位 。 如 果 R 位 已 清 除 , 则 调 试 通 信 读<br />

取 寄 存 器 已 清 除 , 可 以 在 此 写 入 数 据 供 目 标 应 用 程 序 读 取 。<br />

2. 调 试 器 通 过 扫 描 链 2 将 数 据 扫 描 到 调 试 通 信 读 取 寄 存 器 中 。 此 操 作 自 动 设<br />

置 调 试 通 信 控 制 寄 存 器 中 的 R 位 。<br />

3. 目 标 应 用 程 序 轮 询 调 试 通 信 控 制 寄 存 器 中 的 R 位 。 如 果 它 已 设 置 , 则 调 试<br />

通 信 读 取 寄 存 器 中 有 数 据 , 应 用 程 序 可 以 使 用 MRC 指 令 从 协 处 理 器 14 读 ,<br />

以 读 取 该 数 据 。 作 为 读 指 令 的 一 部 分 , R 位 被 清 除 。<br />

位 于 Examples_directory\dcc\inchan.s 中 的 以 下 目 标 应 用 程 序 代 码 片 段 显 示<br />

此 操 作 如 何 工 作 :<br />

AREA InChannel, CODE, READONLY<br />

ENTRY<br />

MOV r1,#3 ; Number of words to read<br />

LDR r2, =indata ; Address to store data read<br />

pollin<br />

MRC p14,0,r0,c0,c0 ; Read control register<br />

TST r0, #1<br />

BEQ pollin ; If R bit clear then loop<br />

read<br />

MRC p14,0,r3,c1,c0 ; read word into r3<br />

STR r3,[r2],#4 ; Store to memory and<br />

; update pointer<br />

SUBS r1,r1,#1 ; Update counter<br />

BNE pollin ; Loop if more words to read<br />

MOV r0, #0x18 ; Angel_SWIreason_ReportException<br />

LDR r1, =0x20026 ; ADP_Stopped_ApplicationExit<br />

SWI 0x123456 ; <strong>ARM</strong> semihosting SWI<br />

7-6 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


调 试 通 信 通 道<br />

AREA Storage, DATA, READWRITE<br />

indata<br />

DCB "Duffmessage#"<br />

END<br />

4. 在 主 机 上 创 建 一 个 输 入 文 件 , 其 中 包 含 ( 例 如 ) And goodbye!。<br />

5. 用 以 下 命 令 汇 编 并 链 接 此 代 码 :<br />

armasm -g inchan.s<br />

armlink inchan.o -o inchan.axf<br />

在 称 为 inchan 的 文 件 中 创 建 了 一 个 可 执 行 映 像 。 要 载 入 并 执 行 该 映 像 , 请 参 阅<br />

您 的 调 试 器 文 档 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 7-7


调 试 通 信 通 道<br />

7.4 中 断 驱 动 调 试 通 信<br />

第 7-4 页 的 轮 询 调 试 通 信 中 提 供 的 示 例 演 示 如 何 轮 询 DCC。 通 过 将 Embedded<br />

ICE 逻 辑 单 元 中 的 COMMRX 和 COMMTX 信 号 链 接 到 中 断 控 制 程 序 , 可 以 将 这 些 示 例 转<br />

换 成 中 断 驱 动 示 例 。<br />

然 后 , 以 上 提 供 的 读 写 代 码 可 以 移 到 中 断 处 理 程 序 中 。<br />

有 关 编 写 中 断 处 理 程 序 的 信 息 , 请 参 阅 第 6-27 页 的 中 断 处 理 程 序 。<br />

7-8 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


调 试 通 信 通 道<br />

7.5 从 Thumb 状 态 访 问<br />

因 为 Thumb 指 令 集 不 包 含 协 处 理 器 指 令 , 所 以 当 内 核 处 于 Thumb 状 态 时 , 不 能<br />

使 用 调 试 通 信 通 道 。<br />

有 三 种 可 能 的 解 决 方 法 :<br />

• 可 以 在 SWI 处 理 程 序 中 编 写 每 个 轮 询 例 程 , 然 后 可 以 在 <strong>ARM</strong> 或 Thumb 状<br />

态 下 执 行 该 处 理 程 序 。 进 入 SWI 处 理 程 序 立 即 将 内 核 转 到 <strong>ARM</strong> 状 态 , 在<br />

该 状 态 下 可 以 使 用 协 处 理 器 指 令 。 有 关 SWI 的 详 细 信 息 , 请 参 阅 第 6 章 处<br />

理 处 理 器 异 常 。<br />

• Thumb 代 码 可 以 交 互 调 用 <strong>ARM</strong> 子 例 程 , 由 该 子 例 程 实 现 轮 询 。 有 关 混 合<br />

使 用 <strong>ARM</strong> 和 Thumb 代 码 的 详 细 信 息 , 请 参 阅 第 4 章 <strong>ARM</strong> 和 Thumb 交 互<br />

操 作 。<br />

• 使 用 中 断 驱 动 通 信 , 而 不 使 用 轮 询 通 信 。 中 断 处 理 程 序 用 <strong>ARM</strong> 指 令 编 写 ,<br />

因 此 可 以 直 接 访 问 协 处 理 器 指 令 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 7-9


调 试 通 信 通 道<br />

7.6 半 主 机<br />

如 果 使 用 $semihosting_enabled=2 的 Multi-ICE, 可 以 将 调 试 通 信 通 道 用 于 半 主<br />

机 。 有 关 的 更 多 信 息 , 请 参 阅 Multi-ICE v2.2 用 户 指 南 。<br />

7-10 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


词 汇 表<br />

Angel<br />

Angel 是 一 个 在 目 标 系 统 上 运 行 的 调 试 监 控 程 序 , 使 您 能 开 发 和 调 试 在 基 于<br />

<strong>ARM</strong> 的 硬 件 上 运 行 的 应 用 程 序 。 Angel 可 调 试 运 行 在 <strong>ARM</strong> 状 态 或 Thumb 状 态<br />

下 的 应 用 程 序 。<br />

ANSI 参 阅 美 国 国 家 标 准 协 会 。<br />

<strong>ARM</strong>ulator<br />

<strong>RealView</strong> <strong>ARM</strong>ulator ISS 是 一 个 指 令 集 模 拟 器 。 它 是 一 个 可 模 拟 各 种 <strong>ARM</strong> 处 理<br />

器 指 令 集 和 体 系 结 构 的 模 块 集 合 。<br />

<strong>ARM</strong>-Thumb 过 程 调 用 标 准 (ATPCS)<br />

<strong>ARM</strong>-Thumb 过 程 调 用 标 准 定 义 在 子 程 序 调 用 过 程 当 中 如 何 使 用 寄 存 器 和 堆 栈 。<br />

ATPCS 参 阅 <strong>ARM</strong>-Thumb 过 程 调 用 标 准 。<br />

半 主 机 (semihosting)<br />

一 种 通 信 机 制 , 目 标 将 应 用 程 序 请 求 的 I/O 操 作 传 送 给 主 机 系 统 处 理 , 而 不 是 试<br />

图 自 身 支 持 I/O。<br />

半 字 (half-word) 一 个 16 位 的 信 息 单 元 。 除 非 另 外 声 明 , 否 则 将 数 字 当 作 无 符 号 整 数 。<br />

CFA 请 参 阅 规 范 框 架 地 址 。<br />

程 序 映 像 请 参 阅 映 像 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 词 汇 表 - 1


词 汇 表<br />

重 新 进 入<br />

子 例 程 具 有 多 个 活 动 代 码 实 例 的 能 力 。 子 例 程 调 用 的 每 个 实 例 具 有 各 自 所 需 的<br />

所 有 静 态 数 据 副 本 。<br />

重 新 确 定 将 为 一 个 运 行 环 境 设 计 的 代 码 移 到 新 运 行 环 境 中 的 过 程 。<br />

重 新 映 射<br />

应 用 程 序 开 始 执 行 之 后 , 更 改 物 理 内 存 或 设 备 的 地 址 。 这 样 做 通 常 是 为 了 在 初 始<br />

化 结 束 时 启 用 RAM 替 代 ROM。<br />

存 储 器 管 理 单 元 (MMU)<br />

控 制 高 速 缓 存 和 存 储 器 块 访 问 权 限 , 并 将 虚 拟 地 址 转 换 为 物 理 地 址 的 硬 件 。<br />

DWARF 一 种 特 殊 的 调 试 格 式 。<br />

大 端 (Big-Endian) 将 一 个 字 的 最 低 位 字 节 存 储 在 比 最 高 位 字 节 更 高 的 地 址 上 的 存 储 结 构 。<br />

读 写 位 置 无 关 (RWPI) 读 / 写 数 据 地 址 可 在 运 行 时 动 态 改 变 。<br />

段 映 像 中 的 一 段 代 码 或 数 据 。<br />

另 请 参 阅 输 入 段 。<br />

堆 可 用 于 创 建 新 变 量 的 计 算 机 内 存 部 分 。<br />

EC++ 一 个 用 于 嵌 入 式 应 用 程 序 的 C++ 变 体 。<br />

ELF 可 执 行 、 可 链 接 格 式 。<br />

分 散 加 载 单 独 分 配 地 址 和 对 代 码 和 数 据 段 进 行 分 组 , 而 不 使 用 单 个 大 块 。<br />

规 范 框 架 地 址 (CFA)<br />

在 DWARF 2 中 , 这 是 指 栈 上 的 一 个 地 址 , 其 指 定 一 个 中 断 函 数 的 调 用 框 架 的<br />

位 置 。<br />

国 际 标 准 组 织 (ISO) 制 定 计 算 机 软 件 和 其 它 行 业 标 准 的 一 个 组 织 。<br />

ICE<br />

线 路 中 仿 真 器 (In Circuit Emulator)。<br />

ISO 参 阅 国 际 标 准 组 织 。<br />

胶 合 代 码 (Veneer )<br />

是 指 当 需 要 改 变 处 理 器 状 态 或 跳 转 目 的 在 当 前 处 理 状 态 所 能 到 达 的 范 围 之 外<br />

时 , 与 程 序 调 用 或 跳 转 配 合 使 用 的 一 小 块 代 码 。<br />

交 互 操 作 (Interworking)<br />

产 生 使 用 <strong>ARM</strong> 和 Thumb 两 种 指 令 的 应 用 程 序 。<br />

紧 偶 合 存 储 器 (TCM) 启 用 后 , 紧 偶 合 存 储 器 将 替 代 块 芯 片 外 存 储 器 区 域 。<br />

局 部 只 能 由 创 建 它 的 子 程 序 访 问 的 对 象 。<br />

词 汇 表 - 2 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


词 汇 表<br />

库 (Library) 由 汇 编 程 序 或 编 译 程 序 产 生 的 目 标 对 象 组 合 形 成 的 一 种 集 合 。<br />

链 接 程 序 (Linker) 由 一 个 或 多 个 源 代 码 汇 编 程 序 或 编 译 程 序 产 生 的 对 象 生 成 一 个 映 像 的 软 件 。<br />

Multi-ICE<br />

用 于 嵌 入 式 系 统 的 基 于 JTAG 的 多 处 理 器 调 试 工 具 。Multi-ICE 是 一 个 <strong>ARM</strong> 注 册<br />

商 标 。<br />

MMU 请 参 阅 存 储 器 管 理 单 元 。<br />

美 国 国 家 标 准 协 会 (ANSI)<br />

制 定 计 算 机 软 件 和 其 它 行 业 标 准 的 一 个 组 织 。<br />

目 标 (Target) 正 在 运 行 目 标 应 用 程 序 的 实 际 目 标 处 理 器 ( 真 实 的 或 模 拟 的 )。<br />

内 联<br />

不 使 用 公 共 子 程 序 , 而 是 在 每 次 使 用 时 以 代 码 重 复 执 行 的 功 能 。 放 置 在 C 或 C++<br />

程 序 中 的 汇 编 程 序 代 码 。<br />

另 请 参 阅 输 出 段 和 嵌 入 式 。<br />

PCS<br />

过 程 调 用 标 准 (Procedure Call Standard)。<br />

另 请 参 阅 ATPCS。<br />

PIC 位 置 无 关 代 码 。<br />

另 请 参 阅 ROPI。<br />

PID 位 置 无 关 的 数 据 或 <strong>ARM</strong> 平 台 无 关 开 发 (PID) 卡 。<br />

另 请 参 阅 RWPI<br />

剖 析 执 行 调 试 程 序 期 间 收 集 统 计 信 息 , 以 度 量 性 能 或 确 定 代 码 的 关 键 区 域 。<br />

嵌 入 式 作 为 固 件 开 发 的 应 用 程 序 。 汇 编 程 序 函 数 在 C 或 C++ 程 序 中 外 联 使 用 。<br />

另 请 参 阅 内 联 。<br />

区 在 映 像 中 , 区 是 指 一 至 三 个 (RO、 RW 和 ZI) 输 出 段 的 相 连 序 列 。<br />

<strong>RealView</strong> 编 译 工 具 (RVCT)<br />

<strong>RealView</strong> 编 译 工 具 是 一 整 套 工 具 以 及 支 持 文 档 和 范 例 , 使 用 户 能 编 写 和 编 译 用<br />

于 <strong>ARM</strong> 系 列 RISC 处 理 器 的 应 用 程 序 。<br />

ROPI 另 请 参 阅 只 读 位 置 无 关 。<br />

RTOS 实 时 操 作 系 统 。<br />

RVCT 请 参 阅 <strong>RealView</strong> 编 译 工 具 。<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 词 汇 表 - 3


词 汇 表<br />

RWPI 请 参 阅 读 写 位 置 无 关 。<br />

软 件 中 断 (SWI) 使 处 理 器 调 用 程 序 员 指 定 的 子 程 序 的 一 个 指 令 。 <strong>ARM</strong> 在 处 理 半 主 机 时 候 用 到 。<br />

SWI 参 阅 软 件 中 断 。<br />

闪 存 (Flash memory)<br />

常 用 于 保 存 应 用 程 序 代 码 的 永 久 内 存 。<br />

输 出 段<br />

具 有 相 同 RO、RW 或 ZI 属 性 的 输 入 段 的 相 连 序 列 。 段 在 更 大 的 、 称 为 区 的 片 段<br />

中 组 合 在 一 起 。 多 个 区 组 合 在 一 起 , 成 为 最 终 的 可 执 行 映 像 。<br />

另 请 参 阅 区 。<br />

输 入 段<br />

输 入 段 包 含 代 码 或 初 始 化 数 据 , 或 者 描 述 应 用 程 序 启 动 前 必 须 设 为 0 的 存 储 器<br />

片 段 。<br />

另 请 参 阅 输 出 段 。<br />

双 字 (Double-word) 一 个 64 位 的 信 息 单 元 。 除 非 另 外 声 明 , 否 则 将 数 字 当 作 无 符 号 整 数 。<br />

TCM 请 参 阅 紧 偶 合 存 储 器 。<br />

线 程 (Thread)<br />

处 理 器 上 的 一 种 执 行 环 境 。 线 程 总 是 与 处 理 器 相 关 , 可 能 ( 或 可 能 不 ) 与 映 像<br />

相 关 。<br />

协 处 理 器 (Coprocessor)<br />

用 于 特 定 运 算 的 附 加 处 理 器 。 通 常 用 于 浮 点 数 学 计 算 、 信 号 处 理 或 内 存 管 理 。<br />

映 像 已 加 载 到 处 理 器 上 可 以 运 行 的 可 执 行 文 件 。<br />

加 载 到 处 理 器 上 并 拥 有 了 执 行 线 程 的 二 进 制 执 行 文 件 。 一 个 映 像 可 能 有 多 个 线<br />

程 。 一 个 映 像 与 运 行 其 默 认 线 程 的 处 理 器 相 关 。<br />

载 入 视 图 在 映 像 载 入 内 存 但 尚 未 开 始 执 行 时 , 区 域 和 段 的 地 址 。<br />

只 读 位 置 无 关 (ROPI) 代 码 和 只 读 数 据 地 址 可 在 运 行 时 动 态 改 变 。<br />

执 行 视 图 在 映 像 载 入 内 存 并 开 始 执 行 之 后 区 域 和 段 的 地 址 。<br />

字 (Word) 一 个 32 位 的 信 息 单 元 。 除 非 另 外 声 明 , 否 则 将 数 字 当 作 无 符 号 整 数 。<br />

词 汇 表 - 4 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


索 引<br />

本 索 引 中 的 条 目 按 字 母 顺 序 列 出 , 符 号 和 数 字 显 示 在 末 尾 。 所 给 出 的 参 考 是 按 页 码 提 供 的 。<br />

A<br />

ANSI C, 请 参 阅 ISO C<br />

<strong>ARM</strong> 和 Thumb 交 互 操 作 4-1<br />

<strong>ARM</strong> 体 系 结 构 5T 版 4-8<br />

ATPCS 4-2, 4-16<br />

BX 指 令 4-5<br />

编 译 程 序 命 令 行 选 项 4-13<br />

编 译 代 码 4-10<br />

C 4-11<br />

C 和 C++ 4-10<br />

C 和 C++ 库 4-13<br />

非 Thumb 处 理 器 4-11<br />

规 则 4-13<br />

过 程 调 用 标 准 4-2<br />

汇 编 语 言 4-5, 4-14<br />

混 合 语 言 4-14, 4-16<br />

检 测 调 用 4-4<br />

胶 合 代 码 4-10, 4-14<br />

示 例 4-8, 4-11, 4-15<br />

叶 函 数 4-10<br />

异 常 4-3<br />

重 复 函 数 4-13<br />

<strong>ARM</strong> 体 系 结 构 5T 版<br />

<strong>ARM</strong> 和 Thumb 交 互 操 作 4-8<br />

asm 关 键 字 , C++ 5-3<br />

ATPCS 3-1<br />

<strong>ARM</strong> 和 Thumb 交 互 操 作 3-16,<br />

4-2<br />

变 体 3-2<br />

参 数 传 递 3-4, 3-9<br />

读 写 位 置 无 关 3-15<br />

浮 点 选 项 3-17<br />

寄 存 器 角 色 3-4<br />

进 程 3-3, 3-15<br />

静 态 基 本 寄 存 器 3-15<br />

局 部 变 量 3-4<br />

可 重 入 函 数 3-15<br />

内 存 状 态 3-3<br />

ROPI 3-14<br />

RWPI 3-15<br />

swstna 3-11<br />

variadic 函 数 3-10<br />

线 程 3-3, 3-15<br />

叶 函 数 3-12<br />

一 致 性 标 准 3-3<br />

栈 限 制 检 查 3-11<br />

栈 术 语 3-6<br />

只 读 位 置 无 关 3-14<br />

ATPCS 选 项<br />

/interwork 4-3<br />

B<br />

BL 指 令 5-6<br />

BX 指 令 4-5, 5-7<br />

0 位 使 用 4-6<br />

半 主 机 模 式 7-10<br />

避 免 在 嵌 入 式 软 件 中 2-11<br />

嵌 入 式 软 件 2-4<br />

编 译 程 序<br />

嵌 入 式 汇 编 程 序 5-12<br />

编 组 寄 存 器 6-3<br />

标 号 , 内 联 汇 编 程 序 5-6<br />

标 量 模 式 3-18<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 索 引 - 1


索 引<br />

C<br />

C<br />

<strong>ARM</strong> 和 Thumb 交 互 操 作 4-10<br />

__asm 说 明 符 5-3<br />

从 C++ 调 用 5-19<br />

从 汇 编 程 序 调 用 5-19<br />

从 汇 编 语 言 访 问 全 局 变 量 5-16<br />

调 用 汇 编 程 序 5-21<br />

链 接 5-19<br />

在 C++ 中 使 用 头 文 件 5-17<br />

CPSR 6-7<br />

C++<br />

asm 关 键 字 5-3<br />

__asm 说 明 符 5-3<br />

从 C 调 用 5-19<br />

从 汇 编 程 序 调 用 5-19<br />

调 用 约 定 5-20<br />

混 合 语 言 中 的 数 据 类 型 5-20<br />

字 符 串 文 字 5-3<br />

操 作 数 表 达 式 , 内 联 汇 编 程 序 5-4<br />

常 数 , 内 联 汇 编 程 序 5-5<br />

超 级 用 户 堆 6-21<br />

超 级 用 户 模 式 6-21<br />

__packed 限 定 符<br />

结 构 中 的 字 段 1-6<br />

指 针 1-6<br />

处 理 器<br />

对 异 常 的 反 应 6-7<br />

纯 端 序 3-19<br />

存 储 器 声 明 , 内 联 汇 编 程 序 5-6<br />

D<br />

代 码<br />

密 度 和 交 互 操 作 4-2<br />

单 区 存 储 器 模 型 2-19<br />

调 试<br />

轮 询 通 信 7-4<br />

通 信 通 道 7-1<br />

中 断 驱 动 通 信 7-8<br />

调 试 器<br />

与 目 标 通 信 7-6<br />

调 用 4-10<br />

从 C++ 调 用 C 5-19, 5-21<br />

从 C++ 调 用 汇 编 程 序 5-19<br />

从 汇 编 语 言 调 用 C 5-19<br />

从 汇 编 语 言 调 用 C++ 5-19<br />

交 互 操 作 胶 合 代 码<br />

交 互 操 作 示 例<br />

语 言 约 定 5-19<br />

堆<br />

超 级 用 户 6-21<br />

E<br />

EMPTY 属 性 2-37<br />

extern "C" 5-17, 5-19, 5-21<br />

F<br />

FIQ 6-2, 6-27<br />

处 理 程 序 6-9, 6-27<br />

寄 存 器 6-27<br />

FPA<br />

未 定 义 的 指 令 处 理 程 序 6-37<br />

FPA 体 系 结 构 3-20<br />

返 回 地 址 6-9<br />

返 回 指 令 6-9<br />

访 问<br />

调 试 通 信 通 道 7-2<br />

非 法 地 址 6-2<br />

分 散 加 载<br />

EMPTY 属 性 2-37<br />

放 置 对 象 2-16<br />

放 置 栈 和 堆 2-18<br />

根 区 2-17<br />

加 载 区 2-13<br />

描 述 文 件 语 法 2-14<br />

嵌 入 式 软 件 2-13<br />

执 行 区 2-13<br />

浮 点<br />

ATPCS 选 项 3-17<br />

FPA 3-20<br />

VFP 3-18<br />

符 号 名 称 , 延 伸 5-19, 5-21<br />

复 位 异 常 6-2<br />

复 位 异 常 处 理 程 序 6-36<br />

G<br />

故 障 地 址 寄 存 器 6-40<br />

关 键 字 , C 和 C++<br />

asm, C++ 5-3<br />

__asm, C 和 C++ 5-3<br />

过 程 控 制 块 6-35<br />

H<br />

函 数 3-10<br />

环 境 切 换 6-35<br />

汇 编 程 序<br />

模 式 更 改 4-6<br />

内 联 , armasm 不 同 之 处 5-7<br />

内 联 , 请 参 阅 内 联 汇 编 程 序<br />

嵌 入 式 , 请 参 阅 嵌 入 式 汇 编 程 序<br />

汇 编 语 言<br />

<strong>ARM</strong> 和 Thumb 交 互 操 作 4-5,<br />

4-14<br />

从 C 调 用 5-21<br />

内 联 , armasm 不 同 之 处 5-7<br />

嵌 入 式 汇 编 程 序 5-12<br />

使 用 胶 合 代 码 的 交 互 操 作 4-14<br />

中 断 处 理 程 序 6-31<br />

混 合 端 序 3-20<br />

混 合 语 言 编 程<br />

<strong>ARM</strong> 和 Thumb 交 互 操 作 4-14,<br />

4-16<br />

J<br />

寄 存 器<br />

调 试 通 信 通 道 7-3<br />

IEEE 754 3-19<br />

基 类<br />

在 混 合 语 言 中 5-20<br />

IMPORT 命 令 5-16<br />

IRQ 6-27<br />

处 理 程 序 6-9<br />

IRQ 异 常 6-2<br />

ISO C, 头 文 件 5-21<br />

JTAG 7-2<br />

加 电 6-2<br />

胶 合 代 码 , 请 参 阅 交 互 操 作<br />

静 态 基 本 3-15<br />

K<br />

可 重 入 函 数 3-15<br />

扩 展 异 常 处 理 程 序 6-41<br />

索 引 - 2 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC


索 引<br />

L<br />

链 接<br />

和 交 互 操 作 4-4, 4-10<br />

链 接 寄 存 器 6-3<br />

链 结 异 常 处 理 程 序 6-41<br />

轮 询 调 试 通 信 7-4<br />

M<br />

命 令 , 汇 编 语 言<br />

IMPORT 5-16<br />

目 标<br />

与 调 试 器 通 信 7-5<br />

N<br />

Nonvariadic<br />

定 义 3-9<br />

函 数 3-9<br />

内 联 汇 编 程 序 5-2<br />

ADR 伪 指 令 5-7<br />

ADRL 伪 指 令 5-7<br />

ALU 标 志 5-6, 5-7<br />

asm 关 键 字 5-3<br />

__asm 说 明 符 5-3<br />

BL 指 令 5-6<br />

BX 指 令 5-7<br />

保 存 寄 存 器 5-8<br />

C 变 量 5-4<br />

C 全 局 变 量 5-16<br />

CPSR 5-6<br />

C, C++ 表 达 式 5-4, 5-7<br />

操 作 数 表 达 式 5-4<br />

常 数 5-5<br />

存 储 器 声 明 5-6<br />

DC 指 令 5-6<br />

调 用 5-3<br />

逗 号 5-8<br />

多 行 5-3<br />

访 问 结 构 5-16<br />

浮 点 指 令 5-8<br />

符 号 扩 展 5-4<br />

复 杂 表 达 式 5-4<br />

寄 存 器 破 坏 5-6<br />

MUL 指 令 5-6<br />

SWI 指 令 5-6<br />

P<br />

示 例 5-9<br />

物 理 寄 存 器 5-5, 5-7<br />

写 入 PC 5-2<br />

虚 拟 寄 存 器 5-5, 5-7<br />

与 嵌 入 式 汇 编 的 不 同 点 5-15<br />

栈 存 寄 存 器 5-8<br />

指 令 扩 展 5-5<br />

中 断 5-9<br />

注 释 5-3<br />

子 程 序 参 数 5-6<br />

# 5-5<br />

PIC 3-14<br />

PID 3-15<br />

Q<br />

嵌 入 式 汇 编 程 序 5-12<br />

调 用 5-12<br />

限 制 5-13<br />

与 C 和 C++ 的 差 异 5-14<br />

与 内 联 汇 编 的 不 同 点 5-15<br />

嵌 入 式 软 件<br />

半 主 机 支 持 2-4<br />

避 免 使 用 半 主 机 2-11<br />

C 库 的 重 新 目 标 化 2-10<br />

C 库 结 构 2-5<br />

初 始 化 序 列 2-23<br />

单 区 模 型 2-19<br />

调 整 映 像 存 储 器 映 射 2-13<br />

定 位 目 标 外 设 2-33<br />

放 置 符 号 2-34<br />

放 置 栈 和 堆 2-18<br />

分 散 加 载 2-13<br />

分 散 加 载 和 存 储 器 设 置 2-28<br />

分 散 加 载 文 件 语 法 2-14<br />

概 述 2-2<br />

根 区 2-17<br />

加 载 区 2-13<br />

加 载 栈 和 堆 2-34<br />

局 部 存 储 器 设 置 2-27<br />

开 发 2-1<br />

链 接 程 序 放 置 规 则 2-7<br />

默 认 存 储 器 映 射 2-6<br />

ROM/RAM 重 新 映 射 2-25<br />

RVCT 操 作 2-4<br />

使 用 RVCT 开 发 2-2<br />

使 用 链 接 程 序 生 成 符 号 2-35<br />

双 区 模 型 2-20<br />

向 量 表 2-24<br />

硬 件 初 始 化 2-30<br />

应 用 程 序 启 动 2-8<br />

运 行 时 存 储 器 模 型 2-19<br />

在 分 散 加 载 文 件 中 放 置 对 象 2-16<br />

栈 指 针 初 始 化 2-29<br />

执 行 模 式 2-31<br />

执 行 区 2-13<br />

嵌 套 SWI 6-22<br />

嵌 套 中 断 6-28<br />

R<br />

ROM/RAM 重 新 映 射 2-25<br />

ROPI 3-14<br />

RWPI 3-15<br />

软 复 位 6-2<br />

软 件 FPA 模 拟 程 序<br />

未 定 义 的 指 令 处 理 程 序 6-37<br />

软 件 中 断 , 请 参 阅 SWI<br />

S<br />

SPSR 6-3, 6-7<br />

T 位 6-5<br />

SWI<br />

处 理 程 序 6-18, 6-19, 6-21<br />

返 回 6-9<br />

间 接 6-25<br />

Thumb 状 态 6-5<br />

SWI 异 常 6-2<br />

SWI 指 令 5-6, 6-18<br />

Thumb 6-5<br />

swstna 3-11<br />

示 例 代 码<br />

位 置 1-2<br />

数 据 类 型 5-20<br />

数 据 中 断<br />

处 理 程 序 6-39<br />

返 回 自 6-11<br />

LDM 6-39<br />

LDR 6-39<br />

STM 6-39<br />

<strong>ARM</strong> DUI 0203BSC © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 索 引 - 3


索 引<br />

STR 6-39<br />

SWP 6-39<br />

异 常 6-2<br />

双 区 存 储 器 模 型 2-20<br />

T<br />

this, 隐 含 5-19<br />

Thumb<br />

and __irq 6-28<br />

BX 指 令 4-5<br />

处 理 异 常 6-7<br />

访 问 DCC 7-9<br />

更 改 到 Thumb 状 态 , 示 例 4-6<br />

内 联 汇 编 程 序 5-2<br />

使 用 重 复 函 数 名 称 4-13<br />

异 常 处 理 程 序 6-7<br />

与 <strong>ARM</strong> 交 互 操 作 4-2<br />

跳 转 表 6-5, 6-19<br />

通 信 数 据 寄 存 器 7-3<br />

通 信 通 道 , 调 试 7-1<br />

W<br />

Variadic<br />

定 义 3-9<br />

函 数 3-10<br />

VFP 体 系 结 构 3-18<br />

未 定 义 指 令 处 理 程 序 6-9, 6-37<br />

未 定 义 指 令 异 常 6-2<br />

未 对 齐 数 据<br />

结 构 中 的 字 段 1-6<br />

LDR 存 取 半 字 1-8<br />

指 针 1-5<br />

X<br />

系 统 模 式 6-43<br />

线 程 3-15<br />

向 量 表 2-24, 6-3, 6-7, 6-13, 6-27<br />

向 量 表 和 缓 存 6-17<br />

向 量 模 式 3-18<br />

协 处 理 器<br />

未 定 义 的 指 令 处 理 程 序 6-37<br />

协 处 理 器 14 7-3<br />

协 议 转 换 器 7-2<br />

Y<br />

延 伸 符 号 名 称 5-19, 5-21<br />

叶 函 数 3-12, 4-10<br />

异 常 6-2<br />

安 装 处 理 程 序 6-13<br />

处 理 器 的 反 应 6-7<br />

FIQ 6-9<br />

返 回 自 6-9<br />

复 位 6-2<br />

IRQ 6-2, 6-9<br />

进 入 6-7<br />

离 开 6-7<br />

SWI 6-2, 6-9<br />

SWI 处 理 程 序 6-18, 6-19, 6-21<br />

使 用 寄 存 器 6-3<br />

使 用 模 式 6-3<br />

数 据 中 断 6-11<br />

未 定 义 指 令 6-2, 6-9<br />

向 量 表 6-3, 6-13<br />

优 先 级 6-3<br />

预 取 中 断 6-2, 6-10<br />

异 常 处 理 程 序<br />

安 装 6-13<br />

从 C 安 装 6-15<br />

返 回 6-8<br />

复 位 6-36<br />

扩 展 6-41<br />

链 结 6-41<br />

嵌 套 6-27<br />

SWI 6-18, 6-19, 6-21<br />

数 据 中 断 6-39<br />

Thumb 6-7<br />

未 定 义 指 令 6-37<br />

预 取 中 断 6-10, 6-38<br />

在 复 位 时 安 装 6-13<br />

中 断 6-27<br />

重 入 6-27<br />

子 例 程 位 于 6-43<br />

隐 含 的 this 5-19<br />

引 用 5-20<br />

用 户 模 式 6-3<br />

预 取 中 断 6-2<br />

处 理 程 序 6-10, 6-38<br />

返 回 自 6-10<br />

语 言 扩 展<br />

嵌 入 式 汇 编 程 序 5-12<br />

运 行 时 存 储 器 模 型<br />

单 区 模 型 2-19<br />

Z<br />

双 区 模 型 2-20<br />

栈 6-3<br />

栈 指 针 6-3<br />

栈 术 语 3-6<br />

指 令 , 汇 编 语 言<br />

BL 5-6<br />

BX 4-5<br />

SWI 5-6, 6-18<br />

SWI (Thumb) 6-5<br />

执 行<br />

速 度 4-2, 6-27<br />

中 断<br />

优 先 化 6-33<br />

中 断 处 理 程 序 6-27<br />

中 断 驱 动 调 试 通 信 7-8<br />

注 释<br />

内 联 汇 编 程 序 5-3<br />

字 符 串 复 制<br />

汇 编 程 序 5-21<br />

数 字<br />

0 位 , 用 于 BX 指 令 中 4-6<br />

符 号<br />

__use_two_region_memory 2-20<br />

索 引 - 4 © 2002、 2003 <strong>ARM</strong> Limited 版 权 所 有 。 保 留 所 有 权 利 。 <strong>ARM</strong> DUI 0203BSC

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!