Re: Writing Assembler!

jhallen@world.std.com (Joseph H Allen)
13 Jun 1997 22:04:45 -0400

          From comp.compilers

Related articles
[12 earlier articles]
Re: Writing Assembler! mark@omnifest.uwm.edu (1997-06-09)
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: jhallen@world.std.com (Joseph H Allen)
Newsgroups: comp.compilers
Date: 13 Jun 1997 22:04:45 -0400
Organization: The World Public Access UNIX, Brookline, MA
References: 97-05-156 97-05-234 97-06-021
Keywords: assembler, parse

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.


; define r-r move instruction.
mov macro 'r1','r2'
db $55 ; Op code for R-R move instruction
db r1+(r2<<4) ; Operand
endm


mov 3,4 ; Move R3 to R4 (generates two bytes)


Naturally there are going to be several forms of the 'mov' instruction, so
the macros should be overloaded:


mov macro #'imm','r'
db $40+r ; Op code and register
db imm ; Value
endm


mov #3,5 ; Move the value 3 to register 5


Now suppose '.' is the current location counter. Sections, segments and so
on can be implemented by setting or recording '.' in assembler symbols.


code macro
set @curseg,. ; Save position in current segment
set curseg,"CODESEG" ; New current segment
set .,CODESEG ; Load . with latest CODESEG value
end


code ; Switch to code segment


You can also use this to make a 'ds' pseudo-op (define space):


ds macro 'n'
set .,n+.
endm


You can use conditional pseudo-ops to make variable length instructions:


bra macro 'target'
if (target-.)>127 || (target-.)<128
db $10 ; Long branch
dw target-.
else
db $11,target-. ; Short branch
endif
endm


bra xyz ; Branch to xyz. Could be 2 or 3 bytes


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 :-)


Best of all you only need about 12 pseudo-ops: macro, endm, if, else, elif,
endif, set, equ, db, dw, dl, include.
--
/* jhallen@world.std.com (192.74.137.5) */ /* Joseph H. Allen */
--


Post a followup to this message

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