返回入门教程首页 主页 | 开发工具 | 应用芯片 | 核心模块  
 
   
 

Forth 系统实现

作者 Brad Rodriguez
编译 赵宇 张文翠

第四部分 汇编器还是 META 编译器

撰写本文的过程贯穿着一个指导思想:“保持最短”。本着这个原则,我把源程序列表安排到另外的地方,对此我表示歉意。现在,我们主要试图讨论以下话题:

你如何开始构造一个 Forth 系统?

你现在已经知道了,主要的 Forth 程序代码是高级串线,它们通常被编译成一系列地址。在 FIG-Forth 时代和早期的 Forth 实践中,汇编语言是唯一可用的程序设计语言工具。汇编语言对于编写 Forth 的 CODE 字是非常好的,但是高级串线必须用一系列的 DW 伪指令来编写。例如, Forth 字:

: MAX ( n n - n) OVER OVER < IF SWAP THEN DROP ;

必须写成

DW OVER,OVER,LESS,ZBRAN

DW MAX2-$

DW SWAP

MAX2: DW DROP,SEMIS

后来,由于可以实际工作的 Forth 系统越来越普及, Forth 编写者开始把 Forth 编译器修改成为交叉编译器,通过运行在 CP/M (或者苹果 II ,或者其它任何什么微机系统)的 Forth 系统,你就可以为其它 CPU 编写 Forth 程序、更改 Forth 系统或者为那个 CPU 编写一个全新的 Forth 系统。

由于是从 Forth 内部创建一个全新的 Forth 系统,这种编译器被称为“META 编译器”。计算机科学的学究们反对这样的称谓,所以有些 Forth 编写者仍然使用“交叉编译”和“重新编译”的术语,这两个术语之间的差异是:“重新编译”只能为相同的 CPU 产生新的 Forth 系统。

现在大多数 PC 机上的 Forth 都是通过 META 编译产生的,但是,在嵌入式系统领域却产生了意见分歧。

使用汇编器编写 Forth 系统的观点认为:

•  META 编译器神秘难懂,你必须完全理解一个 META 编译器然后才能使用它;

•  一般的程序员都懂得汇编器;

•  汇编器对于一个新的 CPU 总是可用的;

•  汇编器处理许多优化(比如长短调用格式);

•  汇编器处理前向引用和特殊的寻址模式,而许多 META 编译器通常不能做到;

•  汇编程序员可以使用熟悉的编辑器和调试工具;

•  代码的产生是完全可见的,没有向程序员“隐藏”任何东西;

•  改变 Forth 模型非常容易,而许多设计的考虑却影响 META 编译器的内部;

使用 META 编译器的观点认为:

•  你是在编写“正常”的 Forth 代码,它当然易于阅读和调试;

•  一但你理解了你的 META 编译器,你就可以很容易地把它移植到新的 CPU 上 ;

•  你需要的唯一工具就是你的计算机上的 Forth 系统;这一点对于没有 PC 的人特别实用,因为现在的许多交叉汇编器要求 PC 机或者工作站。

我用各种方式编写过几个 Forth 系统,所以要作出选择是很痛苦的。我倾向于使用 META 编译器:我发现 Forth 的 MAX 代码比等效的汇编代码易读、易懂。反对使用 META 编译器的观点许多已经被现代的“专业”编译器所克服,如果你使用 Forth 工作,我强烈建议你考虑一个商业化产品。唉,公共的 META 编译器(包括我自己的)依然落后于时代,笨拙同时神秘。

所以我准备为 Forth 程序员提供基本的材料,告诉你作出自己的选择。我将给出 META 形式的MC6809 代码,为 F83 ( IBM PC CP/M ST )提供 META 编译器。 Z80 代码将使用 CP/M 汇编器写成。 8051 代码使用公共的 PC 交叉汇编器编写。

使用 C 语言编写 Forth 系统?

如果不讨论“用C语言编写 Forth 系统”这个新的方法,本文就将是不完全的。 C 语言比汇编器具有更好的可移植性 -- 理论上,你所要作的全部工作就是为任何 CPU 重新编译相同的代码。

这种方法的缺点是:

•  在设计决策选择上更缺少灵活性;比如,不可能实现直接串线编码,也不可能优化寄存器的分配;

•  增加原语之后,你必须重新编译 C 源代码;

•  某些 C 语言实现的 Forth 使用了效率很低的串线技术,比如多个 CASE 语句;

•  大多数 C 编译器产生的代码比汇编语言程序员的代码低效;

但是对于那些 UNIX 系统和不支持汇编语言编程的 RISC 工作站来说,这却是 Forth 得以运行的唯一方法。最完全和广泛使用的公共域 C 语言 Forth 系统是 TILE 。如果你没有运行 UNIX 系统,你可以看一下文件 HENCE4TH_1.2.A 。

为了继续以前的比较,还是先来看看 HENCE4TH 的 MAX 定义。为了清楚起见,我略去了字典头:

_max()

{

OVER OVER LESS IF SWAP ENDIF DROP

}

不使用汇编器,用 C 语言编写核心 CODE 定义,比如,这是 HENCE4TH 的 SWAP 定义:

_swap()

{

register cell i = *(dsp);

*(dsp) = *(dsp + 1);

*(dsp + 1) = i;

}

请注意:用 C 编写 Forth 字有非常不同的技术,所以这些字在 CForth 和 TILE 中可能差异非常大。

在 MC68000 或者 SPARC 工作站上,这样的编码可以产生非常好的代码。不过,一但你计划用 C 来实现 Forth ,你也需要理解用汇编语言实现 Forth 是怎样工作的。所以请继续阅读本文。

参考文献

[CAS80] Cassady, John J., METAForth: A Metacompiler for Fig- Forth , Forth Interest Group (1980).

[MIS90] HenceForth in C , Version 1.2, distributed by The Missing Link, 975 East Ave. Suite 112, Chico, CA 95926, USA (1990). This is a shareware product available from the GEnie Forth Roundtable.

[ROD91] Rodriguez, B.J., letter to the editor, Forth Dimensions XIII:3 (Sep/Oct 1991), p.5.

[ROD92] Rodriguez, B.J., "Principles of Metacompilation," Forth Dimensions XIV:3 (Sep/Oct 1992), XIV:4 (Nov/Dec 1992), and XIV:5 (Jan/Feb 1993). Note that the published code is for a fig-Forth variant and not F83. The F83 version is on GEnie as CHROMIUM.ZIP

[SER91] Sergeant, Frank, "Metacompilation Made Easy," Forth Dimensions XII:6 (Mar/Apr 1991).

[TAL80] Talbot, R.J., fig-Forth for 6809 , Forth Interest Group, P.O. Box 2154, Oakland, CA 94621 (1980).

[TIN91] Ting, C.H., "How Metacompilation Stops the Growth Rate of Forth Programmers," Forth Dimensions XIII:1 (May/Jun 1991), p.17.

 

 

   

(C) ForthChina.com 版权所有 2004-2010
Email:forthchina@163.com