Re: Writing Assembler!

Cyber Surfer <cyber_surfer@wildcard.demon.co.uk>
15 Jun 1997 22:39:34 -0400

          From comp.compilers

Related articles
[13 earlier articles]
Re: Writing Assembler! mark@omnifest.uwm.edu (1997-06-09)
Re: Writing Assembler! landon@netcom.com (1997-06-11)
Re: Writing Assembler! cliffc@risc.sps.mot.com (Cliff Click) (1997-06-11)
Re: Writing Assembler! albaugh@agames.com (1997-06-13)
Re: Writing Assembler! genew@vip.net (1997-06-13)
Re: Writing Assembler! jhallen@world.std.com (1997-06-13)
Re: Writing Assembler! cyber_surfer@wildcard.demon.co.uk (Cyber Surfer) (1997-06-15)
Re: Writing Assembler! rick@tip.nl (1997-06-15)
Re: Writing Assembler! csusb@csv.warwick.ac.uk (1997-06-15)
Re: Writing Assembler! cliffc@risc.sps.mot.com (Cliff Click) (1997-06-19)
| List of all articles for this month |

From: Cyber Surfer <cyber_surfer@wildcard.demon.co.uk>
Newsgroups: comp.compilers
Date: 15 Jun 1997 22:39:34 -0400
Organization: Compilers Central
References: 97-06-050
Keywords: assembler, forth

jhallen@world.std.com uttered these wise words...


> If you're going to go through the trouble of writing an assembler, write a
> sophisticated generic assembler: use macros to define the instruction set.


This is how Forth assemblers work. Opcodes are Forth words, operands
are also Forth words. "Macros" are simply Forth words that call words
in the assembler (another Forth word) vocabulary.


I also like how you can do the same tricks in Lisp and Prolog, using
symbolic expressions. In Lisp, you could use a special form with
sexprs:


(let ((a (+ 3 4)))
        (asm
                (move a d1)
                (addq #1 d1)
                (andi #ff d1)
                (move d1 a))
        a)


A macro might look like this:


(defmacro fudge (a)
        `(asm
                (move ,a d1)
                (addq #1 d1)
                (andi #ff d1)
                (move d1 ,a)))


And used:


(let ((a (+ 3 4)))
        (fudge a)
        a)


Alternately:


(defmacro fudge (e)
        (let ((a (gensym)))
                `(let ((,a ,e))
                          (asm
                                  (move ,a d1)
                                  (addq #1 d1)
                                  (andi #ff d1)
                                  (move d1 ,a))
                            a)))


If you had to do this often, you could write a macro to give you some
"syntactic sugar", to make this kind of macro more concise:


(defasm-macro fudge (a)
        (move a d1)
        (addq #1 d1)
        (andi #ff d1)
        (move d1 a)
        a)


> At this level of generality, the assembler goes from being a trivial
> program, to an N-pass assembler (if you limit the expressions) or a
> symbolic algebra program (if you have no limits). Of course I'd like
> to see someone implement a completely general assembler :-)


Symbolic algebra is easy to do in Lisp. Forth assemblers are usually
one-pass with backpatching.


> Best of all you only need about 12 pseudo-ops: macro, endm, if, else, elif,
> endif, set, equ, db, dw, dl, include.


Yup. Note that in a Lisp or Forth assembler, you'd need less syntactic
sugar, but the principles are the same.
--
<URL:http://www.wildcard.demon.co.uk/> You can never browse enough
    Martin Rodgers | Programmer and Information Broker | London, UK
                        Please note: my email address is gubbish.
--


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.