Annotation of gforth/asm/numref.fs, revision 1.6
1.5 crook 1: \ numref.fs
1.1 pazsan 2:
1.6 ! anton 3: \ Copyright (C) 1998,2001 Free Software Foundation, Inc.
1.3 anton 4:
5: \ This file is part of Gforth.
6:
7: \ Gforth is free software; you can redistribute it and/or
8: \ modify it under the terms of the GNU General Public License
9: \ as published by the Free Software Foundation; either version 2
10: \ of the License, or (at your option) any later version.
11:
12: \ This program is distributed in the hope that it will be useful,
13: \ but WITHOUT ANY WARRANTY; without even the implied warranty of
14: \ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15: \ GNU General Public License for more details.
16:
17: \ You should have received a copy of the GNU General Public License
18: \ along with this program; if not, write to the Free Software
1.4 anton 19: \ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
1.3 anton 20:
1.1 pazsan 21: 0 [IF]
22:
23: This is a generic solution for doing labels (forward and backward
24: references) in an assembler program.
25:
1.5 crook 26: How to use local labels
27: =======================
1.1 pazsan 28:
29: Example:
30:
31: Label 10pause
32: 10 # ldy,
33: 1 $: dey,
34: 1 $ bne,
35: rts,
36: End-Label
37:
38: "n $:" defines an address reference. "n $" returns the address of the
39: reference defined with "n $:".
40:
41:
1.5 crook 42: How to embed local labels in your assembler
43: ===========================================
44:
45: At the moment all references are forward references, meaning all
46: references are resolved at the end of the definition.
1.1 pazsan 47:
48: The Simple Resolver
1.5 crook 49: -------------------
1.1 pazsan 50:
1.5 crook 51: The only special thing is how a label is resolved. Numref does this by
52: executing a resolver-word. For example, consider a two byte opcode
53: with the second byte as branch-offset. The resolver-word would look
54: like this:
1.1 pazsan 55:
1.5 crook 56: : doresolve ( iaddr -- )
1.1 pazsan 57: dup ref-addr @ - swap 1+ X c! ;
58:
59: iaddr is the address of the instruction with the reference that must
60: be resolved. The destination address of the reference is stored at ref-addr.
61:
1.5 crook 62: The resolver-word must be registered like this:
63:
64: "' doresolve TO std-resolver"
65:
66: This is not a deferred word!
1.1 pazsan 67:
68: Complex Resolving
1.5 crook 69: -----------------
1.1 pazsan 70:
1.5 crook 71: To support different cpu-instruction with different operand formats it
72: is possible to find out the type of opcode by accessing the target's
73: memory in doresolve. This works for very simple processors, e.g. for
74: 6502 it is very easy to find out whether we have a 2-byte absolute
75: address or a 1-byte relative address.
1.1 pazsan 76:
1.5 crook 77: If this method is too difficult, it is possible to store additional
1.1 pazsan 78: information in the resolve structure.
79:
80: When assembling an opcode you should find out whether the address is a
1.5 crook 81: reference and then store the xt of a special resolver word in the
82: resolve structure by "ref-resolver !", or store some additional data
83: in the resolve structure by "ref-data !", if one data field is not
84: enough, allocate memory and use ref-data as pointer to it.
1.1 pazsan 85:
1.5 crook 86: Internal structure
87: ==================
1.1 pazsan 88:
1.5 crook 89: There is a heap buffer to store the references. The structure of one
90: entry is:
1.1 pazsan 91:
92: 1 cell ref-link
93: 1 cell ref-flag \ mixture of tag-number
94: \ and tag type
95: 1 cell ref-resolver \ xt of resolver
96: 1 cell ref-addr \ pointer to destination or on reference
97: \ instruction
98: \ (start of the instruction)
99: 1 cell ref-data \ additional information for resolver
100:
101: [THEN]
102:
1.2 pazsan 103: require ./basic.fs
1.1 pazsan 104:
105: also assembler definitions
106:
107: hex
108:
109: 0 value ref-marker \ tells us that address is an reference
110:
111: 0 value ref-now \ points to the reference we are working on
112:
113: : ref-link ref-now ;
114: : ref-flag ref-now cell+ ;
115: : ref-resolver ref-now 2 cells + ;
116: : ref-adr ref-now 3 cells + ;
117: : ref-addr ref-now 3 cells + ;
118: : ref-data ref-now 4 cells + ;
119: : ref-tag-len 5 cells ;
120:
121: : ref-resolve ref-resolver @ execute ;
122:
123: : ref? ( -- )
124: ref-marker
125: false TO ref-marker ;
126:
127: : forward? ( target-addr -- target-addr false | true )
128: dup there = ref? and dup
129: IF nip THEN ;
130:
131: :noname false TO ref-marker ; propper8 chained
132:
133: variable ref-heap 0 ref-heap !
134:
135: ' drop value std-resolver
136:
137: : ref! ( flags/nr -- )
138: \G stores a reference tag
139: \ get mem for tag
140: ref-tag-len allocate throw to ref-now
141: \ build link
142: ref-heap @ ref-link ! ref-link ref-heap !
143: there ref-adr !
144: std-resolver ref-resolver !
145: ref-flag ! ;
146:
147: : $ ( num -- address )
148: \G makes a reference source with the next instruction
149: 01ff and 0200 or ref! there ;
150:
151: : $: ( num -- )
152: \G makes a reference target
153: 01ff and 0a00 or ref! ;
154:
155: : g$: ( num -- )
156: \G makes a reference target for a global label
157: 01ff and 0e00 or ref! ;
158:
159: : g$ ( num -- addr )
160: \G searches a global label and gets its address
161: 01ff and 0e00 or
162: ref-heap BEGIN dup >r @ dup WHILE 2dup cell+ @ =
163: IF nip to ref-now
164: ref-link @ r> !
165: ref-adr @
166: ref-now free throw EXIT THEN
167: r> drop
168: REPEAT 2drop -1 ABORT" could not resolve G label!" ;
169:
170: : kill$: ( -- )
171: \G deallocs the complete reference heap
172: ref-heap @ BEGIN dup WHILE dup @ swap free throw REPEAT drop
173: 0 ref-heap ! ;
174:
175: : find$: ( adr nr -- )
176: 0800 or
177: ref-heap
178: BEGIN dup >r @ dup WHILE 2dup cell+ @ =
179: IF nip to ref-now
180: r> drop
181: ref-resolve EXIT
182: THEN
183: r> drop
184: REPEAT 2drop -1 ABORT" could not resolve label!" ;
185:
186: : solve$
187: ref-heap dup >r @
188: BEGIN dup WHILE dup cell+ @ 0E00 and 0200 =
189: IF to ref-now
190: ref-link @ r@ !
191: ref-now >r
192: ref-adr @ ref-flag @ ( 01ff and ) find$:
193: r> to ref-now
194: ref-link ( dup >r ) @
195: ref-now free throw
196: ELSE
197: r> drop
198: dup >r @
199: THEN
200: REPEAT r> drop drop kill$: ;
201:
202: ' solve$ end-code8 chained
203:
204: previous definitions
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>