返 回

附 文1:编 译 器 和 解 释 器 是 怎 样 工 作 的

这 部 分 是 有 关 语 言 编 译 器、 解 释 器 和 字 节 码 解 释 器 的 历 史 性 综 述。


机 器 代 码 和 汇 编 语 言

---- 最 初 的 时 候, 计 算 机 只 能 处 理 一 种 功 能 非 常 有 限 的 指 令 集, 就 是 大 家 所 知 道 的 机 器 代 码。 机 器 代 码 指 令 从 基 本 上 来 说 是 一 系 列 数 字, 这 些 数 字 对 计 算 机 来 说 有 着 特 定 的 意 义。 以 前, 人 们 都 是 通 过 敲 击 位 于 前 端 面 板 上 的 切 换 开 关 来 将 程 序 写 入 计 算 机 内 存, 从 而 生 成 一 系 列 恰 当 的 数 字( 也 就 是 指 令), 使 计 算 机 有 所 遵 循。

---- 后 来 的 一 次 重 大 飞 跃 发 生 在 计 算 机 被 用 来 翻 译 汇 编 语 言 的 时 候。 汇 编 语 言 与 机 器 代 码 非 常 相 象, 不 同 的 是, 汇 编 语 言 不 遵 循 数 字 指 令 而 是 使 用 字 母 记 忆 法。 例 如“LDA” 代 表 给 计 算 机 的 内 部 累 加 器 加 载 一 个 数 值。 汇 编 语 言 和 机 器 代 码 指 令 之 间 还 处 于 一 一 对 应 的 状 态, 但 是 现 在 计 算 机 开 始 做 把 程 序“ 汇 编” 成 机 器 指 令 的 工 作 了。

---- 下 图 显 示 出 一 个 理 想 的 翻 译 结 果。 这 里LDA 的 机 器 代 码 是1378, 累 加 器( 或 寄 存 器)“A” 的 机 器 代 码 是 数 字00, 变 量“N” 的 内 存 地 址 为1000。 这 个 例 子 可 能 和 现 实 中 的 关 系 不 大, 但 是 它 显 示 出 汇 编 语 言 指 令 是 如 何 同 机 器 代 码 相 关 联 的。

图3 汇 编 语 言 指 令 被 逐 一 翻 译 成 数 字 机 器 代 码 指 令

静 态 编 译 器 是 如 何 工 作 的

图4 编 译 器 将 更 高 级 的 语 句 翻 译 成 多 条 指 令。 连 接 器 则 将 各 种 编 译 结 果( 包 括 先 前 的 编 译 过 的 库) 连 接 起 来, 生 成 一 个 可 执 行 程 序。

---- 当 更 高 级 的 语 言 如C 和PASCAL 问 世 之 后, 又 发 生 了 一 次 重 大 飞 跃。 在 这 些 语 言 中, 一 条 指 令 可 以 翻 译 成 多 行 机 器 代 码。 这 些 语 言 的 翻 译 过 程 也 就 是 我 们 熟 知 的“ 编 译”。 编 译 的 目 的 只 有 一 个: 从 人 们 可 以 读 懂 的 程 序 语 言 中, 生 成 计 算 机 可 以 理 解 的 机 器 代 码。 当 人 们 使 用 更 高 级 的 语 言 时, 机 器 所 做 的 翻 译 工 作 也 就 更 多。

---- 许 多 编 译 结 果 可 以 被 连 接 起 来 产 生 一 个 可 执 行 程 序。 你 通 常 至 少 需 要 将 你 的 程 序 与 先 前 编 译 过 的 系 统 库 连 接 起 来, 以 生 成 一 个 可 执 行 程 序, 这 点 可 从 图N-N 中 看 到。( 也 可 以 在 程 序 运 行 时 再 来 连 接 库。 这 样 的 库 被 称 为 动 态 连 接 库, 或DLL。)

---- 编 译 过 程 基 本 上 有 四 个 步 骤: 标 记, 解 析, 代 码 生 成 和 最 优 化。 在 标 记 步 骤 里, 被 称 为 标 号 的 个 体 条 目 被 识 别 出 来。 举 个 例 子, 在 语 句if(myVal == 123){ 中, 个 体 标 号 是if, (, myVal, ==, 123, ), 和{。

---- 在 解 析 步 骤 中, 个 体 标 号 被 组 合 成 有 意 义 的 语 句。 如 果 组 成 的 语 句 没 有 什 么 意 义, 编 译 器 就 会 产 生 一 个 错 误 信 息。 如 果 编 译 器 确 认 了 这 个 语 句, 那 么 它 就 进 入 下 一 步, 代 码 生 成。

---- 在 代 码 生 成 步 骤 中, 产 生 相 应 的 机 器 代 码。( 注 释: 通 常 是 首 先 生 成 汇 编 语 言, 然 后 这 些 语 言 经 过 汇 编 产 生 机 器 代 码。 但 总 体 上 说 这 些 可 当 做 一 回 事 情 来 看) 一 旦 所 有 的 指 令 都 被 生 成, 编 译 器 就 开 始 了 最 优 化 过 程。 例 如, 一 条 指 令 可 能 在 某 个 存 储 区 域 中 的 某 个 内 部 寄 存 器 中 存 储 了 一 个 值。 下 一 条 指 令 恰 好 要 将 这 个 值 读 入, 并 将 其 应 用 到 另 外 一 个 计 算 中。 优 化 器 会 发 现 此 时 的 低 效 率 操 作, 所 以 会 使 程 序 直 接 使 用 内 部 寄 存 器 中 的 值, 从 而 消 除 额 外 的 读 操 作。

语 言 解 释 器 是 如 何 工 作 的

图5 语 言 解 释 器 基 本 上 是 一 个 大 循 环。 它 得 到 一 条 指 令 后, 分 析 并 执 行 该 指 令, 然 后 再 去 读 取 下 一 条 指 令, 持 续 上 述 过 程, 直 到 它 读 完 所 有 指 令 或 有 一 条 指 令 告 诉 它 停 止 工 作。

---- 尽 管 编 译 器 能 够 生 成 非 常 有 效 率 的 程 序, 但 是 编 译 器 却 要 耗 费 时 间 的。 编 译 器 的 优 化 性 能 越 好, 它 要 耗 费 的 时 间 也 就 越 长。 这 对 程 序 的 生 产 来 说 固 然 很 好, 但 对 学 习 编 程 序 的 人 来 说 却 是 一 个 现 实 问 题。 他 们 为 了 运 行 一 个 小 程 序 也 许 不 得 不 编 译30 或40 次。 编 译 时 间 很 长, 就 会 使 学 习 变 得 令 人 沮 丧 而 感 受 不 到 乐 趣。

---- 许 多 语 言 如Basic 是 这 样 解 决 该 问 题 的, 它 们 让 计 算 机 充 当 一 个 解 释 器。 解 释 器 不 是 将 整 个 程 序 编 译 成 机 器 代 码 后 再 让 它 运 行, 而 是 端 坐 在 那 里, 循 环 反 复 地 寻 找 指 令。 每 次 当 它 得 到 一 条 新 指 令 之 后, 就 开 始 做 标 记, 分 析 它, 然 后 执 行 同 该 语 句 相 关 的 机 器 代 码。

---- 命 令shell, 如DOS 和CSH 是 只 能 确 认 有 限 数 目 命 令 的 解 释 器。 解 释 器 的 循 环 接 受 一 条 命 令, 处 理 它, 并 促 使 你 发 出 另 一 条 命 令。 典 型 的Basic 语 言 命 令 解 释 器 也 是 这 样 运 转 的。

---- 你 马 上 会 发 现, 此 种 方 式 效 率 低 下 的 一 个 原 因 是, 无 法 对 结 果 代 码 进 行 优 化。 既 然 每 条 指 令 一 经 发 现 马 上 就 被 执 行, 你 完 全 有 可 能 在 一 条 指 令 中 存 储 了 一 个 值, 而 在 下 条 指 令 中 却 不 得 不 重 新 去 寻 找 它。 而 且, 这 样 的 纯 解 释 器 会 将 所 见 的 每 一 行 都 做 标 记 并 进 行 分 析。 当 你 一 次 就 处 理 一 行( 如 命 令shell), 或 当 你 处 理 一 个 非 常 小 的 程 序 的 时 候, 这 也 许 并 不 坏, 但 是 当 你 处 理 一 个 很 大 的 程 序 时, 它 就 会 极 大 地 减 慢 运 行 速 度。

字 节 码 解 释 器 是 如 何 工 作 的

---- 二 十 年 前 在 圣 地 亚 哥, 加 利 福 尼 亚 大 学 生 研 制 出 了UCSD Pascal, UCSD Pascal 促 使 一 种 系 统 流 行 了 起 来, 这 种 系 统 就 是 目 前Java 所 使 用 的 系 统。 它 使 用 字 节 码 解 释 器 使 解 释 工 作 更 有 效 率。 下 图 显 示 了 字 节 码 解 释 器 是 如 何 工 作 的。

图6 字 节 码 解 释 器 把 前 面 几 个 步 骤 中 翻 译 好 的 指 令 当 作 其 输 入。 它 也 运 行 一 个 循 环, 但 它 不 做 其 他 语 言 解 释 器 所 做 的 任 何 标 记 和 分 析 工 作。

---- 利 用 这 个 系 统, 一 个 程 序 首 先 被 翻 译 成 为 一 系 列 的 字 节 码。 这 个 完 成Java 翻 译 任 务 的 程 序 是javac-java "complier"( 编 译 器)。 这 些 字 节 码 是 虚 拟 地 运 行 在 某 个 实 际 上 并 不 存 在 的 计 算 机( 即 虚 拟 计 算 机) 上 的 数 值 机 器 码。 解 释 器 完 成 对 这 些 字 节 码 的 理 解, 并 将 它 在 本 地 机 器 上 运 行。 它 以 一 种 循 环 的 方 式 来 运 行, 每 见 到 一 个 字 节 码 就 将 它 在 本 地 计 算 机 上 运 行。Java 虚 拟 机(JVM) 就 是 解 释 器 的 一 个 例 子。

---- 利 用 字 节 码 解 释 器 意 味 着 表 征 和 解 析 在 翻 释 阶 段 进 行。 因 此 字 节 码 解 释 器 比 语 言 解 释 器 更 快。 所 生 成 的 结 果 程 序 比 完 全 编 译 过 的 程 序 更 为 紧 凑。 或 许 更 重 要 的 是, 字 节 码 解 释 程 序 是 可 移 植 的。 它 们 可 以 在 任 何 机 器 上 运 行, 只 要 这 些 机 器 上 具 有 能 够 正 确 翻 译 字 节 码 的 虚 拟 机。

---- 然 而, 当 字 节 码 被 解 释 时, 还 需 要 一 个 翻 译 步 骤。 解 释 器 识 别 相 应 的 机 器 指 令, 并 且 执 行 这 些 指 令。 与 任 何 单 个 翻 译 相 关 的 额 外 开 销 是 微 不 足 道 的, 但 是 所 有 执 行 指 令 集 聚 起 来 的 额 外 开 支 也 是 非 常 大 的。 在 一 个 大 程 序 中, 这 种 额 外 开 支 相 对 于 简 单 执 行 一 系 列 完 全 编 译 过 的 指 令 来 说, 变 得 十 分 巨 大。 另 外, 这 种 方 式 几 乎 不 能 进 行 任 何 程 度 的 优 化。 因 此 对 于 字 节 码 解 释 程 序 来 说, 好 的 消 息 是, 这 种 程 序 紧 凑, 具 有 平 台 独 立 性, 不 好 的 消 息 是, 它 运 行 缓 慢。

返 回


中国计算机世界出版服务公司版权所有