Imported Upstream version 2.9.0
[debian/cc1111] / as / doc / README
1 (README 2-Apr-1998 by John Hartman.  jhartman@compuserve.com)
2
3 I have made several modifications to the CUG292 assemblers and
4 linker, beginning with version 1.7 (the most recent I know of).
5
6 The original assembler was written by
7  * Alan R. Baldwin
8  * 721 Berkeley St.
9  * Kent, Ohio  44240
10
11 To conserve space on my web site, this ZIP file does not include all
12 of the files in the original CUG292 release.  In particular, the
13 assembler test files and ASSIST monitors have been removed.  All source
14 files and documents are included.  The original is widely available
15 on the net.
16
17 Your comments and bug reports are solicited.
18
19 The changes are of three types
20 1) bug fixes and small changes
21 2) an 8051 version of the assembler
22 3) generation of line and symbol information for NoICE
23
24 ========================================================================
25 MISCELLANEOUS CHANGES
26
27 * There is a bug in LKMAIN: it tests S_DEF flag in "s_flag".
28   No one else uses s_flag in the linker - S_DEF is defined in s_type
29   instead.  Presumably LKMAIN should use s_type as well?  Changed.
30
31 * There is a portability problem in aslex: the test
32     while (ctype[c=get()] & ~(SPACE | ILL))
33   causes an infinite loop with my (old Zortech) compiler:
34   ILL = 0x80, SPACE=0.  When I read a null at the end of a line,
35   ctype[] returns "ILL".  My compiler sign extends this 0x80 to int 0xFF80.
36   Sign extend on ~ILL makes 0x7F into 0xFF7F.  The result of the AND is
37   true and we spin.  I changed this to
38     while (ctype[c=get()] & (0xFF - (SPACE|ILL)))
39
40 * I made changes to mlookup() so that mnemonics and pseudo-ops are always
41   case insensitive, regardless of the CASE_SENSITIVE flag.  This simplifies
42   using the assembler on existing code.
43
44 * The scheme described below for debug information can make for very long
45   symbol names.  Thus, I have modified the assembler and linker to allow
46   names up to 80 characters, moving the name strings out of the sym struct.
47   This will save significant heap space over simply increasing NCPS to 80.
48
49 * I have added one module, ASNOICE.C, to each assembler; and one module,
50   LKNOICE.C, to the linker.  My make files are named XSnnnn.MAK for the
51   asseblers, and XSLINK.MAK for the linker.  I have not modified any
52   of the original make or project files, since I have no means to test
53   them.
54
55 ========================================================================
56 8051 ASSEMBLER
57
58 I was somewhat surprised that there was no AS8051 - so I wrote one.
59 It is comprised of the modules:
60     i8051.h
61     i51pst.c
62     i51mch.c
63     i51adr.c
64     i51ext.c
65     appendk.txt "Appendix K" about the 8051 for the documentation
66
67 I added four attributes to the .area directive to support
68 the 8051's multiple address spaces:
69    CODE for codespace
70    DATA for internal data
71    BIT  for internal bit-addressable
72    XDATA for external data.
73
74 These will typically be used as follows (names are examples):
75         .area   IDATA (DATA)
76         .area   IBIT (BIT)
77         .area   MYXDATA (REL,CON,XDATA)
78         .area   MYCODE (REL,CON,CODE)
79
80 The default segment, _CODE, should not be used for the 8051.  For
81 compatibility reasons, _CODE is allocated in "DATA" space.  You
82 should always define an area in the CODE space.
83
84 DETAILS:
85
86 i51mch.c is not especially pretty - it includes some brute-force switch
87 statements which could, I suspect, be trimmed down by application of
88 a few appropriate functions.
89
90 The 8051 includes two instructions, AJMP and ACALL, which have eleven
91 bit destination addresses.  The upper three address bits are encoded
92 into the top three bits of the op-code.  In order to achieve this, I
93 was forced to make changes to several ASxxx and LKxxx modules:
94     asm.h       line 179 equate for R_J11, 583 outr11 prototype
95     asout.c     lines 1087-1132 function outr11: output 11 bit dest
96     aslink.h    line 131 equate for R_J11
97     lkrloc.c    lines 354-377 link/locate 11 bit destination
98
99 The definition of R_J11 is as (R_WORD | R_BYT2)
100 A comment in lkrloc says
101     * R_WORD with the R_BYT2 mode is flagged
102     * as an 'r' error by the assembler,
103     * but it is processed here anyway.
104 This is no longer true, so the code in question is #defined out
105 in the linker only.  I suspect that this would cause problems
106 if a module with R_WORD | R_BYT1 by other cause were to be processed.
107
108 I am not entirely happy with outr11 in the case where the destination
109 is an absolute value.  The ideal would be to pass the value thru to the
110 linker, and resolve at link time whether or not the address is within
111 2K of the instruction location.  Unfortunately, I couldn't figure out
112 how to pass an absolute value to the linker, as it has no area.  Thus,
113 I interpreted absolute values as being relative to the beginning of the
114 current area, as is done in the other assemblers for relative branch
115 instructions.  I am less happy with this solution here, as a 2K range
116 is far larger than the +-128 for a branch instruction.  I can envision
117 code such as
118         reset = 123
119         ...
120         ajmp  reset
121
122 If the ajmp is in a relocatable area, the effect will be not at all what
123 is desired.  If you can offer any other solution, I would appreciate it.
124
125 ========================================================================
126 SOURCE-LEVEL DEBUG OF ASSEMBLY CODE WITH NoICE
127
128 1) The switch "-j" has been added to the assembler.  This causes
129    assembly lines to generate line number information in the object
130    file.  You may also wish to use the "-a" switch to make all symbols
131    global.  Non-global symbols are not passed to the object file.
132
133 2) The assemblers will pass any line beginning with the characters
134    ";!" (semi-colon, exclamation point) intact to the object file.
135    You can use such comments in your assembly modules to embed NoICE
136    commands in your source code.
137
138 3) The switch "-j" has been added to the linker.  This causes a
139    NoICE debug file, with extension ".NOI" to be created.  All symbol
140    and line number information in the object files, as well as any
141    ";!" comments will be included.  Specifying the -j switch will force
142    a map file to be produced as well.
143
144 4) The linker will process any line beginning with the characters
145    ";!" (semi-colon, exclamation point) by removing the ";!" and
146    passing the remainder of the line to the .NOI file (if any).
147    This allows NoICE commands to be placed as ";!" comments in
148    the assembly file, and passed through the assember and linker
149    to the .NOI file.
150
151 5) If the linker is requested to produce a hex output file (-i or -s
152    switches), a LOAD command for the hex file will be placed in the
153    .NOI file (if any).
154
155 6) The linker will output the ";!" lines after all symbols have been
156    output.  Thus, such lines can contain NoICE commands which refer to
157    symbols by name.
158
159 ========================================================================
160 SOURCE-LEVEL DEBUG OF C CODE FOR NoICE
161
162 This section is primarily of interest to compiler writers.
163
164 Compilers which produce assembly code can pass debug information
165 through the assembler and linker to the NoICE command file.  In
166 addition, the linker will provide special processing of symbols
167 with certain formats described below.
168
169 1) The switch "-j" should NOT be used on assembly files which
170    represent compiler output.  Instead, the compiler should generate
171    line number symbols for each code-producing source line as
172    described below.  if your project contains a mixture of C and assembly
173    source files, you may wish to use "-j" on the assembly modules.
174
175 2) The assemblers will pass any line beginning with the characters
176    ";!" (semi-colon, exclamation point) intact to the .REL file.
177    The compiler can make use of this fact to pass datatype information
178    and stack offsets for automatic symbols through the assembler and
179    linker to NoICE.  This is described in detail below.
180
181 3) The switch "-j" has been added to the linker.  This causes a
182    NoICE debug file, with extension ".NOI" to be created.  Contents
183    will be as described below.  Specifying the -j switch will force
184    a map file to be produced as well.
185
186 4) The linker will process any line beginning with the characters
187    ";!" (semi-colon, exclamation point) by removing the ";!" and
188    passing the remainder of the line to the .NOI file (if any).
189
190 5) If the linker is requested to produce a hex output file (-i or -s
191    switches), a LOAD command for the hex file will be placed in the
192    .NOI file (if any).
193
194 6) The linker will process symbols with names of the form
195         text
196
197    into NoICE DEFINE (global symbol) commands in the .NOI output file
198         DEF name symbolvalue
199
200 7) The linker will process symbols with names of the form
201         text.integer
202
203    into NoICE FILE and LINE (line number) commands in the .NOI output file.
204    It will assume that "text" is the file name without path or extension,
205    that "integer" is the decimal line number within the file, and that
206    the value of the symbol is equal to the address of the first instruction
207    produced by the line.
208
209 8) The linker will process symbols with names of the form
210         text.name
211
212    into NoICE FILE and DEFINESCOPED commands in the .NOI file
213    (if any), to define file-scope variables:
214         FILE text
215         DEFS name symbolvalue
216
217 9) The linker will process symbols with names of the form
218         text.name.name2
219
220    into NoICE FILE, FUNCTION, and DEFINESCOPED commands in the
221    .NOI file (if any), to define function-scope variables:
222         FILE text
223         FUNC name
224         DEFS name2 symbolvalue
225
226 10) The linker will process symbols with names of the form
227         text.name.name2.integer
228
229    into NoICE FILE, FUNCTION, and DEFINESCOPED commands in the
230    .NOI file (if any), to define function-scope variables, to allow
231    multiple scopes within a single C function.  "Integer" is a scope
232    number, and should be zero for the first scope, and increment
233    for each new scope within the function.  Since NoICE cannot currently
234    cope with scope finer than function, it will produce symbols of
235    the form:
236         FILE text
237         FUNC name
238         DEFS name2_integer symbolvalue
239
240    The trailing "_integer" will be omitted for integer == 0 (function).
241
242 11) The linker will process symbols with names of the form
243         text.name..FN
244
245    into NoICE FILE, DEFINE, and FUNCTION commands in the .NOI
246    file (if any), to define the start of a global function:
247         FILE text
248         DEF  name symbolvalue %code
249         FUNC name symbolvalue
250
251 12) The linker will process symbols with names of the form
252         text.name..SFN
253
254    into NoICE FILE, DEFINESCOPED, and SFUNCTION commands in the .NOI
255    file (if any), to define the start of a file-scope (static)
256    function:
257         FILE text
258         DEFS name symbolvalue %code
259         SFUNC name symbolvalue
260
261 13) The linker will process symbols with names of the form
262         text.name..EFN
263
264    into NoICE ENDFUNCTION commands in the .NOI file (if any) to
265    define the end of a global or file-scope function:
266         ENDF name symbolvalue
267
268 14) The linker will output the symbols in each "area" or memory
269    section in order of increasing address.
270
271 15) The linker will output the ";!" lines after all symbols
272    have been output.
273
274 The features listed above may be used to add full source-level
275 debug information to assembly files produced by a compiler.  The
276 example file ctest1.c, and the hypothetical ctest1.s produced by
277 compiling it illustrate this.  The comments in the file describe
278 the information, but would not be present in an actual implementation.
279
280 1) Begin each file with a ";!FILE" specifying the file name and its
281    original extension (usually ".c"), and with the path if the file is
282    not in the current directory.
283         ;!FILE ctest1.c
284
285 2) Define any basic data types: char defaults to S08.  Redefine as U08 or
286    ASCII if you desire.  "int" defaults to S16.  Redefine if necessary.
287         ;!DEFT 0 char %ASCII
288
289 3) Define any data structures, typedefs, enums, etc. (C generally
290    does this per source file.  Types will remain in scope unless
291    redefined).  For example, the C structure
292
293         typedef struct {
294            char  c;
295            int   i;
296            int   ai[ 10 ];
297            int   *pi;
298         } STR;
299
300    would generate the commands:
301         ;!STRUCT 0. STR
302         ;!DEFT 0. c %char
303         ;!DEFT 1. i %int
304         ;!DEFT 3. ai %int[10.]
305         ;!DEFT 23. pi %*int
306         ;!ENDS 25.
307
308    Since the user can change input radix at will, it is generally
309    recommended to specify radix explicitly in the ;! commands: by
310    a trailing "." for decimal, or leading "0x" for hex.
311
312 4) Use ;!FUNC, (or ;!SFUNC), ;!DEFS, and ;!ENDF to define any
313    function arguments and local variables.  The function
314         void main( void )
315         {
316            /* declare some local variables */
317            char lc, *plc;
318            int *pli;
319            int *lnpi;
320            int *lfpi;
321            ...
322
323    would generate stack-based symbol definitions with their datatypes.
324    (Note that the stack offsets are not passed to the assembler by
325    name, as they need not be relocated.  Thus, it is the compiler's
326    duty to generate these.  Note that the 68HC11 TSX instruction
327    increments the value of SP by one.  Thus, "SP+nn" should use
328    "nn" values one greater than for use as offsets from X.
329         ;!FUNC main
330         ;!DEFS lfpi SP+6. %*int
331         ;!DEFS lnpi SP+8. %*int
332         ;!DEFS pli SP+10. %*int
333         ;!DEFS plc SP+12. %*char
334         ;!DEFS lc SP+14. %char
335
336    When all local variables and parameters have been defined, the
337    function scope must be closed:
338         ;!ENDF
339
340 5) In general, it is desirable to generate two symbols for each
341    function:  one with an underbar, at the first byte of the
342    function, so that the disassembler will show it as the destination
343    of the JSR; and a second without an underbar at the address of
344    the first source line after stack frame is set up.  The latter
345    will be a common breakpoint location.
346
347    CUG292 can generate global symbols by using a "::"
348         _main::
349                 tsx
350                 xgdx
351                 subd #44
352                 xgdx
353                 txs
354
355 6) Once the stack frame is set up, declare the beginning of the
356    function body.  The value of this symbol is the lowest address
357    which NoICE will consider to be within the function for scoping
358    purposes.
359         ctest1.main..FN::
360
361 7) Each C source line which produces code should emit a symbol
362    consisting of the file name without path or extension, followed
363    by the line number (in decimal) in the C source file.
364         ctest1.56::
365                 ldd #6
366                 std  _gestr
367
368 8) Declare the end of the function body.  The value of this symbol
369    is the highest address which NoICE will consider to be within the
370    function for scoping purposes.  The address must be on or before
371    the RTS, so that it does not overlap the following function.
372    Normally, the address will be the last C source line in the
373    function before stack frame is destroyed.
374         ctest1.main..EFN::
375                 xgdx
376                 addd #44
377                 xgdx
378                 txs
379                 rts
380
381 9) Global variables defined in the file, and their datatypes, may be
382    defined at any time.  Debugging is most convenient if the
383    traditional C leading underbar is omitted.  The global declarations
384         int gi;
385         STR *pgstr;
386
387    would generate:
388         ;!DEF gi %*int
389         gi::
390                 .blkb 2
391
392         ;!DEF pgstr %*STR
393         pgstr::
394                 .blkb 2
395
396    Here, the ";!" command defines the datatype, which is unknown to
397    the assembler, while the "::" defintion defines the value, which
398    is unknown until link time.
399
400 10) File-scope static variables, and their datatypes, must be defined
401    between the ;!FILE and the ;!ENDFILE in order to set proper scope.
402    Debugging is most convenient if the traditional C leading underbar
403    is omitted.  The static declarations
404         static int si;
405         static STR sstr;
406
407    would generate:
408         ;!DEFS si %*int
409         ctest1.si::
410                 .blkb 2
411
412         ;!DEFS sstr %STR
413         ctest1.sstr::
414                 .blkb 25
415
416    We note that while the ;!DEFS must be between ;!FILE and ;!ENDFILE,
417    the "::" definitions may be elsewhere in the file if it is
418    convenient, as the symbol name carries the scoping information.
419
420 11) Function-scope static variables, and their datatypes, must be
421    defined between the ;!FUNC (or ;!SFUNC) and the corresponding
422    ;!ENDF in order to set proper scope.  Debugging is most convenient
423    if the traditional C leading underbar is omitted.  The static
424    declarations
425         void main( void )
426         {
427                 static int si;
428                 static STR sstr;
429
430    would generate:
431         ;!FUNC main
432
433    at some point, and then
434         ;!DEFS si %*int
435         ctest1.main.si::
436                 .blkb 2
437
438         ;!DEFS sstr %STR
439         ctest1.main.sstr::
440                 .blkb 25
441
442    We note that while the ;!DEFS must be between ;!FUNC and ;!ENDF,
443    the "::" definitions may be elsewhere in the file if it is
444    convenient, as the symbol name carries the scoping information.
445
446 12) After all code, data, and ;! defintions, declare end of file.
447    This is necessary to prevent mangled scope when several modules
448    are linked together.
449         ;!ENDFILE
450
451         CTEST1.C - sample C source code
452         CTEST1.S - output from ImageCraft compiler, hand-doctored
453                    to add additional debug information
454         CTEST2.C - second C module
455         CTEST2.S - output from ImageCraft compiler, undoctored
456         CTEST.BAT - assemble and link CTEST1+CTEST2
457
458 Run CTEST.BAT to produce CTEST1.NOI, a NoICE command file.
459
460 end README