<< Previous Message Main Index Next Message >>
<< Previous Message in Thread This Month Next Message in Thread >>
Date   : Tue, 15 Mar 2005 03:42:07 +0000 (GMT)
From   : Greg Cook <debounce@...>
Subject: Re: Assembler bug

On 06 Mar 2005 20:27:21 +0000, Jonathan Graham Harston wrote:
> > Message-ID: <Marcel-1.53-0305194004-1cbzokP@...>
>  
> "A.Weston" <a.weston2@...> wrote:
> > Here's an interesting bug I read in an old magazine:
> > 
> > If you define a zero page variable within assembler an listing then
> the
> > assembler will assume this is a two-byte variable on the first pass
> and
> > as a result any subsequent branch instructions will point to the
> wrong
> > place.
>  
> No, that's not an assembler bug, that's a programmer bug.
  
True, defining all your labels at the start is a good idea, but there
is possibly some macro trick (or legacy spaghetti code) where this is
impossible.  At worst, you have to assemble in three passes:

>LIST
   10 FOR P=1 TO 3
   20 IF P=3 THEN pass=3 ELSE pass=0
   30 P%=&C00:REM User characters
   40 [OPT pass
   50 LDA loc:BPL exit \ Return ?loc if +ve
   60 EOR #&FF:ADC #1 \ Two's complement
   70 .exit:RTS
   80 ]
   90 loc=&80
  100 NEXT
>RUN
0C00          OPT pass
0C00 A5 80    LDA loc
0C02 10 04    BPL exit \ Return ?loc if +ve
0C04 49 FF    EOR #&FF
0C06 69 01    ADC #1 \ Two's complement
0C08          .exit
0C08 60       RTS

> If you do:
>  
>    LDA location
>  
> How does the assembler know whether 'location' is a zero-page
> location or a 16-bit location on the first pass? It doesn't! Not
> unless you've defined it before the assembler gets to that line.

It turns out the assembler just substitutes undefined variables with
P%.  (A side effect is that 'hanging' branches hang the program,
inviting the programmer to investigate and hopefully correct.)

> It can't read your mind! It has to assume it's a 16-bit address,

The assembler effectively assumes the reference is going to be nearby,
so instructions that run in the greater address space default to
two-byte operands, and code that runs in zero page defaults to
single-byte operands.  In either case, forward references of the
ordinary kind are resolved in two passes.  (Zero page code suffers the
same 'bug' with references to the greater address space.)  Personally
though, using precious ZP memory for code is a terrible waste...

>CLEAR
>10:
>20 FOR pass=0 TO 3 STEP 3:REM Back to two passes
>30 P%=&70:REM BASIC User ZP
>RUN
0070          OPT pass
0070 A5 80    LDA loc
0072 10 04    BPL exit \ Return ?loc if +ve
0074 49 FF    EOR #&FF
0076 69 01    ADC #1 \ Two's complement
0078          .exit
0078 60       RTS

Greg

Send instant messages to your online friends http://uk.messenger.yahoo.com 
<< Previous Message Main Index Next Message >>
<< Previous Message in Thread This Month Next Message in Thread >>