Assembler in Common Lisp
From: Greg Menke (gregm-news_at_toadmail.com)
Date: 07/29/04
- Next message: Thomas Lindgren: "Re: Your Guru Paul Graham is getting trashed on Slashdot."
- Previous message: Don Geddis: "Re: new benchmark results for 8 CL implementations in cliki.net"
- Next in thread: Jeff: "Re: Assembler in Common Lisp"
- Reply: Jeff: "Re: Assembler in Common Lisp"
- Reply: Christophe Turle: "Re: Assembler in Common Lisp"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: 29 Jul 2004 17:18:39 -0400
Sometime last Fall I asked a question about how CL might be used to
create a macro assembler for a microcontroller. I finally got around
to giving it a try and I think its working. Its not entirely
complete, there are more instructions & directives to implement and
things related to generating binary images to do, but I wanted to
sanity check some of the basic design. The assembler is working now
with the instructions I've implemented so far. Hopefully this is
enough detail to suggest if I'm doing things right or not, which I
hope you might comment on.
- Assembler implementation is in package 'asm51. The assembler
creates a "private" package & imports 'common-lisp and the assembler
compile-time symbols. Code to be assembled is presented to the
Assembler via a stream.
- Assembly occurs with *package* set to the private package, so all of
common-lisp and the assembler directives are directly available to
the user's sourcecode.
- Two directives are implemented as macros, "defcode" and "defdata".
They accept a lambda-ish arrangement of sexp-formatted assembly, as
follows;
(defcode temp
(nop)
(mov A 1)
(call 'xyzpdq)
(ret))
Which causes the assembler to create a symbol named "TEMP" in the
private package & save off all sexps after the symbol name as the
contents of the symbol, to be assembled later. Note the quoted
symbol, it refers to a symbol introduced by an invocation of defcode
elsewhere in the source.
- Each instruction is set up as a defmethod with specializations for
all the legal combinations of parameters. In the (nop) example,
there is only one specialization. The (mov ..) example, a number of
specializations exist, including one that serves this case, a
literal value is moved to the accumulator register. All the cpu
registers exist as variously typed symbols to support the
specializations.
- First, (read) is used to get each sexp. (eval) is used to execute
it. This causes the defcode/defdata macros to expand & execute,
introducing each symbol in the sourcecode.
- After all symbols are introduced, the contents of each symbol are
individually (eval)'ed, causing the specialized defmethods to be
invoked which themselves yield Lisp "object" macros that will be
used last to generate the binary output. Additionally, this step
provides the runtime size of the code or data represented by the
symbol, so now each symbol knows how long it is & runtime addresses
are then assigned.
- Symbol references like 'xyzpdq above are resolved last. Once each
symbol has a runtime address, the address is stored to the symbol's
symbol-value, so the presence of a symbol in an expression will
yield its runtime address in the last step.
- Lastly the "object" macros in each symbol are (eval)ed, yielding the
output binary.
The upshot of (read) and (eval) here is that the user can employ all
of Common Lisp as an assembly-time "metalanguage". I think this means
I can use defmacros ,etc.. in the source code to build a fancy macro
assembler. By introducing each symbol given in the source as a
full-blown Lisp symbol, I don't have to parse anything by hand or keep
anything anywhere outside an instance of a defstruct in each symbol's
plist which the assembler references as necessary. The assembler
internals sanity check incoming values as code is emitted, so
incorrect types/magnitudes will be caught.
The assembler source remains nice and simple, the bulk of the content
is defintions of the cpu registers and the instruction defmethods.
Does this sound like the right sort of approach?
Thanks,
Gregm
- Next message: Thomas Lindgren: "Re: Your Guru Paul Graham is getting trashed on Slashdot."
- Previous message: Don Geddis: "Re: new benchmark results for 8 CL implementations in cliki.net"
- Next in thread: Jeff: "Re: Assembler in Common Lisp"
- Reply: Jeff: "Re: Assembler in Common Lisp"
- Reply: Christophe Turle: "Re: Assembler in Common Lisp"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|