将GAS宏转换为MASM宏

时间:2014-07-28 00:26:24

标签: assembly macros masm gas

我正在研究一个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

0 个答案:

没有答案