Saving one byte using INC instead of STA/ADC/STA?

Discuss all aspects of programming here. From 8-bit through to modern architectures.
Post Reply
User avatar
colinhoad
Posts: 31
Joined: Fri Mar 15, 2019 2:25 pm
Contact:

Saving one byte using INC instead of STA/ADC/STA?

Post by colinhoad » Sat Jul 06, 2019 5:39 am

Hello,

I am working my way (very slowly) through Ian Birnbaum's excellent book on assembly language programming for the Beeb. I try as much as possible to follow along with each of his examples to make sure I'm understanding it fully. I'm stumped, though, because I've reached a point where I can't seem to re-create what he says I should be able to. There is a program in the book on page 25 (second edition) that can be used to add two unsigned bytes together where the result may be larger than 255. He later rewrites this program on page 54 using the INC command, and claims that by doing this the resulting assembled program is one byte less in size. But no matter what I try, both programs (the original and the rewritten version using INC) come out at 16 bytes in total. Am I missing something? I really do want to grasp why he says the use of INC is more efficient when adding two numbers whose result might be > 255 but I am struggling.

Original program:

Code: Select all

10  NUM1=&70 : NUM2=&71 : SUML=&72 : SUMH=&73
20  DIM P% 50
30  [OPT3
40  .START
50  LDA NUM1
60  CLC
70  ADC NUM2
80  STA SUML
90  LDA #0
100 STA SUMH
110 ADC SUMH
120 STA SUMH
130 RTS:]
140 REPEAT
150   INPUT"First number to be added",?NUM1
160   INPUT"Second number to be added",?NUM2
170   CALLSTART
180   PRINT?NUM1+?NUM2,256*?SUMH+?SUML
190   UNTIL FALSE
Rewritten using INC:

Code: Select all

10  NUM1=&70 : NUM2=&71 : SUML=&72 : SUMH=&73 : DIM START 50
20  FOR I%=0 TO 3 STEP 3 : P%=START
30  [OPTI%
50  LDA #0
60  STA SUMH
70  LDA NUM1
80  CLC
90  ADC NUM2
100 STA SUML
110 BCC NOCARRY
120 INC SUMH
130 .NOCARRY
140 RTS:]
150 NEXTI% : REPEAT
160   INPUT"First number to be added",?NUM1
170   INPUT"Second number to be added",?NUM2
180   CALLSTART
190   PRINT?NUM1+?NUM2,256*?SUMH+?SUML
200   UNTIL FALSE
Assembled output from original program:

Code: Select all

1A82		OPT3
1A82		.START
1A82 A5 70	LDA NUM1
1A84 18		CLC
1A85 65 71	ADC NUM2
1A87 85 72	STA SUML
1A89 A9 00	LDA #0
1A8B 85 73	STA SUMH
1A8D 65 73	ADC SUMH
1A8F 85 73	STA SUMH
1A91 60		RTS
Assembled output from rewritten program:

Code: Select all

1AB8		OPTI%
1AB8 A9 00	LDA #0
1ABA 85 73	STA SUMH
1ABC A5 70	LDA NUM1
1ABE 18		CLC
1ABF 65 71	ADC NUM2
1AC1 85 72	STA SUML
1AC3 90 02	BCC NOCARRY
1AC5 E6 73	INC SUMH
1AC7		.NOCARRY
1AC7 60		RTS
Can anyone shed any light? I can't believe this is a misprint, since he makes the case for using INC at length, so it must be something I'm just not getting...

cmorley
Posts: 1055
Joined: Sat Jul 30, 2016 7:11 pm
Location: Oxford
Contact:

Re: Saving one byte using INC instead of STA/ADC/STA?

Post by cmorley » Sat Jul 06, 2019 6:09 am

It is one byte shorter if you are using a variable outside zero page I think.

User avatar
colinhoad
Posts: 31
Joined: Fri Mar 15, 2019 2:25 pm
Contact:

Re: Saving one byte using INC instead of STA/ADC/STA?

Post by colinhoad » Sat Jul 06, 2019 6:58 am

cmorley wrote:
Sat Jul 06, 2019 6:09 am
It is one byte shorter if you are using a variable outside zero page I think.
Thank you so much! You're absolutely right, I changed my variables to the first page (i.e. &0170 for NUM1, &0171 for NUM2 etc.) and the programs assembled with one less byte in the rewritten program, as the BCC command only requires a single byte to increment the program counter for the branch.

Thanks again, you've honestly saved me hours of brain racking...
Last edited by colinhoad on Sat Jul 06, 2019 7:03 am, edited 1 time in total.

User avatar
Rich Talbot-Watkins
Posts: 1556
Joined: Thu Jan 13, 2005 5:20 pm
Location: Palma, Mallorca
Contact:

Re: Saving one byte using INC instead of STA/ADC/STA?

Post by Rich Talbot-Watkins » Sat Jul 06, 2019 7:11 am

There's no need for the first STA SUMH at all. The best version of this routine would just end with:

Code: Select all

LDA #0
ADC #0
STA SUMH

User avatar
colinhoad
Posts: 31
Joined: Fri Mar 15, 2019 2:25 pm
Contact:

Re: Saving one byte using INC instead of STA/ADC/STA?

Post by colinhoad » Sat Jul 06, 2019 7:19 am

Rich Talbot-Watkins wrote:
Sat Jul 06, 2019 7:11 am
There's no need for the first STA SUMH at all
Very good point, the first program performs just the same if rewritten as you suggest! Hmm, not sure why it was specified that way in the book originally :?

User avatar
tricky
Posts: 3818
Joined: Tue Jun 21, 2011 8:25 am
Contact:

Re: Saving one byte using INC instead of STA/ADC/STA?

Post by tricky » Sat Jul 06, 2019 7:25 am

or to save another byte ;)

Code: Select all

LDA #0
ROL A
STA SUMH

User avatar
colinhoad
Posts: 31
Joined: Fri Mar 15, 2019 2:25 pm
Contact:

Re: Saving one byte using INC instead of STA/ADC/STA?

Post by colinhoad » Sat Jul 06, 2019 7:32 am

Ooh, "ROL"! Not got to that command in my 6502 adventures yet :D

User avatar
Lardo Boffin
Posts: 1710
Joined: Thu Aug 06, 2015 6:47 am
Contact:

Re: Saving one byte using INC instead of STA/ADC/STA?

Post by Lardo Boffin » Sat Jul 06, 2019 8:29 am

I would be very interested to see a modern take on one of these books written with 30 years of experience of 6502. [-o<
Atom, issue 5
BBC model B 32k issue 4, 16k sideways RAM, Watford 12 ROM board, Acorn 6502 coproc
BBC model B 32k issue 7, turboMMC, Opus Challenger 3 512k, Pi 3 coproc
USA Model B
BBC Master, Datacentre + HDD, pi co-proc, econet, NULA

User avatar
kieranhj
Posts: 835
Joined: Sat Sep 19, 2015 10:11 pm
Location: Farnham, Surrey, UK
Contact:

Re: Saving one byte using INC instead of STA/ADC/STA?

Post by kieranhj » Sat Jul 06, 2019 8:37 am

colinhoad wrote:
Sat Jul 06, 2019 6:58 am
Thank you so much! You're absolutely right, I changed my variables to the first page (i.e. &0170 for NUM1, &0171 for NUM2 etc.) and the programs assembled with one less byte in the rewritten program, as the BCC command only requires a single byte to increment the program counter for the branch.
Also just to note that in general you don’t want to use page &100 for variables as this is reserved for the stack in 6502. You might not encounter any problems at those addresses in this example but for something more complicated down the line you could end up with the stack corrupting your variables, or vice-versa which would likely manifest as a crash after an RTS.

The Advanced User Guide has a full memory map for all BBC models, which is very helpful.

On the topic of zero page, this is also considered ‘special’ by the 6502 and a prized resource. All reads/writes are 1 cycle shorter and addressing zero page requires 1 less byte, as you’ve seen. As you develop larger programs it may not be possible to keep all your vars in ZP so becomes important to decide which are critical for size and speed.
Bitshifters Collective | Retro Code & Demos for BBC Micro & Acorn computers | https://bitshifters.github.io/

User avatar
colinhoad
Posts: 31
Joined: Fri Mar 15, 2019 2:25 pm
Contact:

Re: Saving one byte using INC instead of STA/ADC/STA?

Post by colinhoad » Sat Jul 06, 2019 1:38 pm

kieranhj wrote:
Sat Jul 06, 2019 8:37 am
Also just to note that in general you don’t want to use page &100 for variables as this is reserved for the stack in 6502. You might not encounter any problems at those addresses in this example but for something more complicated down the line you could end up with the stack corrupting your variables, or vice-versa which would likely manifest as a crash after an RTS.
Thanks, Kieran - I do remember reading at the start of the book that certain memory pages and addresses are reserved and didn't think to check again before trying my 'quick and dirty' variable re-addressing. I'll bear that in mind for when I (hopefully one day!) write more complex programs than simple calculators... This whole experience has also taught me several new things about the zero page, so all information gratefully received. :)

Post Reply