1 BAS -- the Basic Assembler Supplement
2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 Once upon a time, this was meant to be a commercial Straylight
5 product. I never got around to writing the documentation.
7 BAS is Yet Another tool for people who use the BASIC assembler. The
8 odd thing is that Straylight use Acorn's `objasm' assembler for all
9 our `real' work. The idea was to produce a procedure library for
10 generating linkable AOF code from BASIC, and the functionality grew
11 from there. Features are:
13 * Generates AOF version 2 object code.
14 * Handles literal pools. (I'll come to them.)
15 * Translates (a simple subset of) objasm header files.
16 * A small collection of other tools.
18 BAS is almost entirely written in assembler, with a BASIC procedure
19 library thrown in. You don't need to worry about that -- the code
20 is tacked on the end of the BASIC file, so it all comes as one
23 _____________________________________________________________________________
27 BAS is Free Software; you can redistribute it and/or modify
28 it under the terms of the GNU General Public License as published by
29 the Free Software Foundation; either version 2, or (at your option)
32 BAS is distributed in the hope that it will be useful, but WITHOUT
33 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
34 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
35 License for more details.
37 You should have received a copy of the GNU General Public License
38 along with BAS; if not, write to the Free Software Foundation, Inc.,
39 675 Mass Ave, Cambridge, MA 02139, USA.
41 Of course, you can do what you like with the output of BAS.
43 _____________________________________________________________________________
47 I'll assume you understand how linkable objects work. We'll be
48 here all day if you don't.
50 All code must be in an `area'. You start an area by saying
52 FNarea("NAME", "ATTRIBUTES")
54 The name can be anything you like; common names are `C$$Code' for
55 C code, and similar. Dollars are popular for some reason.
57 The attributes define properties of areas, which in turn affect
58 positioning and access permissions. We've tried to use the same
61 CODE -- area contains code (implies `READONLY')
62 COMDEF -- definitons for a common area
63 COMMON -- overlay areas with this name
65 NOINIT -- initialise this area with zeros
66 READONLY -- I don't need to write to this area
67 DEBUG -- contains debugging information
69 By default, areas with the same name are concatenated. You get
70 given symbols `NAME$$Base' and `NAME$$Limit' to tell you the
71 boundaries of the complete area called `NAME', which is useful for
74 Attribute names can be separated by anything you like -- they're
75 parsed by the BASIC library using INSTR. Objasm uses commas, so
78 A program generating AOF code will usually look something like this:
88 FNarea("Foo$$Code", "CODE, READONLY")
93 PROCbas_aofSave / PROCbas_aofSaveAs(FILENAME)
95 Here, `SIZE' is the amount of space to reserve for the code, and
96 `FILENAME' is the name to save it as. The PROCbas_aofSave function
97 uses the value of <BAS$Output> as a default filename: this allows
98 you to declare an alias
100 Set Alias$BasAsm Set BAS$Output %1|mBASIC -quit %0
102 which you can use in Makefiles.
104 You're not limited to one assembly per source file -- you can create
105 any number of object files, although each one must start with a
106 call to PROCbas_aofInit and end with PROCbas_aofSave[As].
108 Note that you must begin each assembly by calling FNpass -- this
109 will set the P% and O% variables appropriately for the assembly, and
110 make sure that the BAS code understands where you are in the
113 You can export a synbol (so that other object files can see it) by
114 calling FNexport; for example:
117 .hello stmfd r13!,{r0,r14}
118 ldr r0,FNlitsz("Hello, world")
123 Because AOF allows a wider range of identifiers than BASIC, you can
124 `alias' names as you export them; for example:
126 FNexport("foo", "My$$FooishThing")
128 takes the value represented in the BASIC variable `foo' and exports
129 it as `My$$FooishThing' in an object file.
131 You import values in the same way:
137 stmfd r13!,{r1-r3,r12,r14}
140 ldmnefd r13!,{r1-r3,r12,r14}
141 ldr r0,FNliterr(1,"Not enough memory")
142 swi "OS_GenerateError"
146 (I'll explain the FNlit... and FNltorg macros later. Bear with me.)
148 You can also FNimportAs a symbol with a funny name:
150 FNimportAs("Image$$RW$$Limit","program_end")
152 fetches the limit of the read-write area of the image, telling you
153 where the program ends. This is quite handy.
156 How this all works is possibly interesting. It (ab)uses offset
157 assembly, directing output (O%) to a buffer BAS allocates for you,
158 and starting P% at &FC000000, which is an illegal instruction, and
159 hopefully unlikely to appear in `real' code. Once the assembly's
160 finished, BAS runs through and picks out references to things in
161 with addresses &FCxxxxxx and creates relocation directives for them
162 in the AOF file. Imported things get given addresses &FDxxxxxx.
163 Assuming these values don't appear in genuine code, we're OK. Just
164 in case you want to make arbitrary data appear in the object, BAS
165 has directives for disabling and reenabling relocation:
171 won't munge anything between them.
177 marks the entry point in an AIF program -- execution will start
178 here. That's all there is to it.
180 _____________________________________________________________________________
182 LITERALS AND LITERAL POOLS
184 Data like strings and absolute addresses are a pain in the BASIC
185 assembler -- you have to make up labels for them, and then reference
186 them. BAS tries to handle this sort of thing for you, which is
187 rather more pleasant of it.
189 At any point in an assembly, BAS is building a `literal pool'. You
190 create a literal using one of the supplied directives, and BAS is
191 responsible for putting it in a literal pool; it gives you the
192 address at which the literal will be placed in the finished output.
193 The current literal pool will be written to the assembly when you
194 call FNltorg. A literal pool is also written at the very end of
199 adr r0,FNlitsz("Hello, world")
208 equs "Hello, world" + CHR$(0)
210 The literal creation macros provided are:
212 * FNlitw(WORD) stores a 32-bit value WORD at a word-aligned
215 FNimportAs("Image$$RW$$Limit", "prog_end")
216 ldr r0,FNlitw(prog_end)
218 puts the address of the end of the program in R0.
220 * FNlits(STRING) stores a string, unterminated, and non-word-
221 aligned. This isn't very useful.
223 * FNlitmagic(STRING) stores an unterminated string at a word-
224 aligned address. This is for things like
226 ldr r1,FNlitmagic("TASK")
228 so you don't have to remember that this is &4B534154. I
231 * FNlitsz(STRING) stores a null-terminated string at a non-word-
232 aligned address. This is useful for all kinds of messages.
234 * FNliterr(NUM, STRING) stores a RISC OS error block at a word-
237 If you need some kind of structure which isn't provided, you can
238 build it yourself. PROClitStart informs BAS that it's meant to
239 assemble a literal; FNliteral completes the literal, returning
240 the address where BAS will eventually put it. FNlitAlign does
241 the same job, only it word-aligns the literal.
243 _____________________________________________________________________________
245 READING OBJASM HEADERS
247 FNget(FILENAME) reads an Objasm-format header file. It's not perfect
250 Objasm directives supported are: `^', `#'. `EQU', and `IMPORT'.
251 This is hopefully enough for most purposes. The `*' synonym for
252 `EQU' is also supported.
254 BAS can't understand Objasm macros. Instead, it understands `active
255 comments'. The only one implemented is `LIB':
259 which loads the BASIC procedure library FILENAME. A BAS macro
260 library `foo' must contain a function FNfoo_test, which is used by
261 BAS to see whether the library is loaded.
263 _____________________________________________________________________________
267 BAS defines a whole slew of constants:
269 * r0-r15, R0-R15, a1-a4, v1-v6, sb, sl, fp, sp, SP, lr, LR,
270 lk, LK, pc and PC are all set to the appropriate register
273 * EQ, NE etc. are set to the appropriate condition code values.
275 FNalign aligns the output position to a word boundary, padding with
276 zero bytes. FNreserve(SIZE) writes SIZE zero bytes to the output.
278 FNbin(FILENAME) inserts the contents of the file FILENAME into the
279 output, protecting it from relocation. FNfSize(FILENAME) returns
280 the size of the file FILENAME. This can be handy for setting up
283 FNws_start clears a storage-area counter to zero. FNws_base(VALUE)
284 sets the counter to VALUE. FNws_align word-aligns the counter.
285 FNws(SIZE) returns the counter, and increases it by SIZE. FNws_word,
286 and FNws_byte are equivalent to FNws(4) and FNws(1) respectively.
287 These are useful for laying out workspace areas and data structures.
289 FNadrl(REG, ADDR) assembles a long ADR; FNadrccl(COND, REG, ADDR)
290 assembles a conditional long ADR. FNaddl(REG, BASE, OFFSET)
291 assembles a long ADD; FNaddccl(COND, REG, BASE, OFFSET) does the
294 FNldrl(REG, ADDR) assembles a long LDR; FNldrccl(COND, REG, ADDR)
295 assembles a conditional long LDR. FNldrrl(REG, BASE, OFFSET)
296 assembles a long non-PC-relative LDR;
297 FNldrrccl(COND, REG, BASE, OFFSET) does that conditionally.
299 _____________________________________________________________________________
301 BUILDING BAS FROM SOURCES
303 This is quite involved. You need to have:
305 * Acorn Desktop Assembler or later
307 * An implementation of `sed' -- I recommend the port of GNU sed.
309 * Straylight's basic library set (`header', `swis' and `stream')
310 available from the same place you got this from.
312 * A copy of Cy Booker's `ccrunch' BASIC compressor. If you don't
313 have this, edit `remnames' and remove the `ccrunch' line -- the
314 BAS output file will be a little larger, but that's OK.
316 Build the ARM code part by running the Makefile. Now run `Setup'
317 to mangle the nice BASIC library part, and to tack the code on
318 the end. That should be it.
320 _____________________________________________________________________________
324 Dunno. Straylight were hoping to sell it for maybe fifteen quid a
325 go. We use it in-house for building simple AOF-outputting tools;
326 our message-file and template-file compilers are BAS-based, for
327 example. (These are available as part of the SDLS and Sapphire
328 packages, if they're out yet.)
330 _____________________________________________________________________________