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