我正在研究一个Forth编译器JonesForth,它是在GAS中为Linux编写的。我的计划是重写它,在MASM32中进行一些小的改动,以提高我对Forth内部机制的理解并重新学习汇编编程(我上次在6509处理器上使用汇编20世纪80年代初。)
我可以使用汇编代码本身,我想想我理解GAS宏实际上做什么。但我很难将它们转换为MASM宏(可能是因为我在MASM宏上仍然有点粗略)。
这是琼斯写的(我的评论添加在方括号中):
[link ard DOCOL是预先定义的......]
内置词------------------------------------------- ---------------------------
还记得我们的词典条目(标题)吗?让我们将它们与代码字和数据字结合在一起,看看如何:DOUBLE DUP +;真的看起来很记忆。
pointer to previous word
^
|
+--|------+---+---+---+---+---+---+---+---+------------+------------+------------+------------+
| LINK | 6 | D | O | U | B | L | E | 0 | DOCOL | DUP | + | EXIT |
+---------+---+---+---+---+---+---+---+---+------------+--|---------+------------+------------+
^ len pad codeword |
| V
LINK in next word Points to codeword of DUP
最初我们不能写'#34;:DOUBLE DUP +;" (即那个文字字符串)在这里,因为我们还没有任何东西可以阅读字符串,在空格处分解,解析每个单词等等。所以相反,我们必须使用定义内置单词GNU汇编程序数据构造函数(如.int,.byte,.string,.ascii等等 - 如果您不确定它们,请在GAS信息页面中查找它们。)
漫长的道路将是:
.int <link to previous word>
.byte 6 // Length
.ascii "DOUBLE" // String
.byte 0 // Padding
DOUBLE: .int DOCOL // Codeword
.int DUP // Pointer to codeword of DUP
.int PLUS // Pointer to codeword of +
.int EXIT // Pointer to codeword of EXIT
这会很快变得相当繁琐,所以我在这里定义一个汇编器宏,以便我可以写:
defword "DOUBLE",6,,DOUBLE
.int DUP,PLUS,EXIT
我会得到完全相同的效果。
不要过分担心这个宏的具体实现细节 - 这很复杂!
.macro defword name, namelen, flags=0, label
.section .rodata
.align 4
.globl name_\label
name_\label :
.int link // Link
.set link,name_\label
.byte \flags+\namelen // Flags + length byte
.ascii "\name" // The name
.align 4 // Padding to next 4 byte boundary
.globl \label
\label :
.int DOCOL // Codeword - the interpreter
// List of word pointers follow
.endm
同样,我想用一种方法来编写用汇编语言编写的单词。会有不少 其中一开始是因为,好吧,一切都必须在集会之前开始 足够的&#34;基础设施&#34;能够开始写Forth单词,但我也想定义 汇编语言中的一些常见Forth单词用于速度,即使我可以在Forth中编写它们。
这就是DUP在内存中的样子:
Pointer to previous word
^
|
+--|------+---+---+---+---+------------+
| LINK | 3 | D | U | P | code_DUP ---------------------> Points to the assembly
+---------+---+---+---+---+------------+ code used to write DUP,
^ Len Codeword which ends with NEXT.
|
LINK in next word
同样,为了简化编写标题,我将编写一个名为defcode的汇编程序宏。与上面的defword一样,不要担心宏的复杂细节。
.macro defcode name, namelen, flags=0, label
.section .rodata
.align 4
.globl name_\label
name_\label :
.int link // Link
.set link,name_\label
.byte \flags+\namelen // Flags + length byte
.ascii "\name" // The name
.align 4 // Padding to next 4 byte boundary
.globl \label
\label :
.int code_\label // Codeword
.text
.globl code_\label
code_\label : // Assembler code follows
.endm
[示例...(TCFA,INCR4和EXIT是预定义的地址标签,NEXT是预定义的MACRO)]
defword ">DFA",4,,TDFA
.int TCFA // >CFA (Get code field address)
.int INCR4 // 4+ (Add 4 to it to get to next word)
.int EXIT // EXIT (Return from FORTH word)
defcode "DROP",4,,DROP
pop %eax // Drop top of stack
NEXT