Annotation of gforth/asm/numref.fs, revision 1.9

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>