Branching - how does it work?

Building your first 6502-based project? We'll help you get started here.
Post Reply
Atlantis
Posts: 122
Joined: 19 Jun 2018

Branching - how does it work?

Post by Atlantis »

I have to admit, I am a little bit confused. I always thought that situation is straightforward.
Let's assume we have a following situation.

Code: Select all

LDA variable
CMP #$10
BEQ LABEL
; these are instructions executed when variable != 16
; program simply continues to execute, increasing program counter
; you have to take care of it, to not hit LABEL after it's done
; for example by using RTS or JMP instruction
LABEL:
; this is set of instructions executed when variable == 16
; program jumps here after BEQ LABEL
But recently I was looking at a code compiled by CC65. There is a following fragment of a main() function.

Code: Select all

if (variable < 16) {
	hd44780_putc('A');
}
while(1) { }
It is compiled as:

Code: Select all

lda     _variable
cmp     #$10
L001F:	bcs     L001F
lda     #$41
jsr     _hd44780_putc
L001E:	jmp     L001E
Can anyone explain me how does it works? It looks like bcs instruction points at itself, by using L001F label.
Can it be done that way? Will bcs simply jump to the next label (L001E in that case) if variable is less or equal than 0x10?
hmn
Posts: 21
Joined: 07 May 2017

Re: Branching - how does it work?

Post by hmn »

Code: Select all

lda     _variable
cmp     #$10
L001F:   bcs     L001F
That is simply an endless loop if _variable >= 16. So that is equivalent to your C code. The compiler just decided to implement your endless loop twice.
JenniferDigital
Posts: 92
Joined: 25 May 2015

Re: Branching - how does it work?

Post by JenniferDigital »

No, you were on the right track the first time!

Firstly, the C code you wrote isn't functionally identical to the assembly code and secondly, CC65 doesn't produce very optimal code. CC65 still needs some of it's rough edges and documentation polishing and on my wishlist is support for floats and doubles (and I don't care what the whingers say about floats and doubles being slow on a 6502, they can go away).

BEQ branches when Z is set,
BCS branches when C is set.

you could have said "!=" in C instead.
whartung
Posts: 1004
Joined: 13 Dec 2003

Re: Branching - how does it work?

Post by whartung »

DigitalDunc wrote:
Firstly, the C code you wrote isn't functionally identical to the assembly code and secondly, CC65 doesn't produce very optimal code.
It is a curious situation that the compiler implemented the endless loop twice, however.
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: Branching - how does it work?

Post by barrym95838 »

Atlantis wrote:
Will bcs simply jump to the next label (L001E in that case) if variable is less or equal than 0x10?
I believe that "BCS" on the 65xx is equivalent to "BCC" or "BHS" from 680x/680x0-lands, which means branch if unsigned >= (assuming the flags were preconditioned by a compare or subtract instruction).
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)
User avatar
BillO
Posts: 1038
Joined: 12 Dec 2008
Location: Canada

Re: Branching - how does it work?

Post by BillO »

While it would have been no more efficient, it would have read better and been less confusing if the compiler code read:

Code: Select all

lda     _variable
cmp     #$10
L001F:   bcs     L001E
lda     #$41
jsr     _hd44780_putc
L001E:   jmp     L001E
Bill
JimBoyd
Posts: 931
Joined: 05 May 2017

Re: Branching - how does it work?

Post by JimBoyd »

barrym95838 wrote:
Atlantis wrote:
Will bcs simply jump to the next label (L001E in that case) if variable is less or equal than 0x10?
I believe that "BCS" on the 65xx is equivalent to "BCC" or "BHS" from 680x/680x0-lands, which means branch if unsigned >= (assuming the flags were preconditioned by a compare or subtract instruction).
BCS on the 6502 branches on carry set and BCC branches on carry clear. Subtraction clears the carry if the subtraction results in a borrow and sets it otherwise. Comparisons have the same effect on the carry flag as subtraction. In the following code snippet it may appear that nothing is subtraced from memory location COUNTER but because the carry flag is cleared, one is subtracted from COUNTER.

Code: Select all

define COUNTER_LO  $0
define COUNTER_HI  $1
LDA #$00
STA COUNTER_LO
LDA #$02
STA COUNTER_HI
CLC
LDA COUNTER_LO
SBC #$00
STA COUNTER_LO
LDA COUNTER_HI
SBC #$00
STA COUNTER_HI
BRK
This example runs on easy 6502 http://skilldrick.github.io/easy6502/ as I think this will be easier to follow than my Forth assembler syntax.

Cheers,
Jim
JimBoyd
Posts: 931
Joined: 05 May 2017

Re: Branching - how does it work?

Post by JimBoyd »

I forgot to mention when you try this code on easy 6502 http://skilldrick.github.io/easy6502/, after assembling the code, click the monitor button and the debugger button. Single step through the code to see the carry flag and memory locations change.
JimBoyd
Posts: 931
Joined: 05 May 2017

Re: Branching - how does it work?

Post by JimBoyd »

I ran across this the other day. Just wish I found it sooner.
The SBC, TSX, and TXS Instructions of the 6502 and 6800
by B.T.G. Tan
Dr Dobbs Journal #79 May 1983 page 67 http://6502.org/documents/publications/ ... s_journal/
It's in Volume 8.
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Branching - how does it work?

Post by GARTHWILSON »

JimBoyd wrote:
I ran across this the other day. Just wish I found it sooner.
The SBC, TSX, and TXS Instructions of the 6502 and 6800
by B.T.G. Tan
Dr Dobbs Journal #79 May 1983 page 67 http://6502.org/documents/publications/ ... s_journal/
It's in Volume 8.
page 280 of the .pdf file
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
User avatar
BigEd
Posts: 11464
Joined: 11 Dec 2008
Location: England
Contact:

Re: Branching - how does it work?

Post by BigEd »

BTW another way to read Mike's scans of DDJ is at the internet archive:
https://archive.org/details/dr_dobbs_journal

and then we can link directly to the article:
https://archive.org/stream/dr_dobbs_jou ... 9/mode/1up

Thanks for the tip!
ghedger42
Posts: 4
Joined: 27 Nov 2018

Re: Branching - how does it work?

Post by ghedger42 »

Make _variable a volatile, to force the compiler to read it each time and prevent optimizing the infinite loop.
User avatar
BigEd
Posts: 11464
Joined: 11 Dec 2008
Location: England
Contact:

Re: Branching - how does it work?

Post by BigEd »

(Welcome to the forum ghedger42!)
User avatar
Mike Naberezny
Site Admin
Posts: 295
Joined: 30 Aug 2002
Location: Northern California
Contact:

Re: Branching - how does it work?

Post by Mike Naberezny »

JimBoyd wrote:
I ran across this the other day. Just wish I found it sooner.
The SBC, TSX, and TXS Instructions of the 6502 and 6800
by B.T.G. Tan
Dr Dobbs Journal #79 May 1983 page 67 http://6502.org/documents/publications/ ... s_journal/
It's in Volume 8.
It's great to see the Dr. Dobb's scans are being put to good use.

This particular article is also available as a separate PDF under Dr. Dobb's Selected Articles (suggested by Ed).
White Flame
Posts: 704
Joined: 24 Jul 2012

Re: Branching - how does it work?

Post by White Flame »

It seems quite an omission that it doesn't actually show you how to do stack-relative addressing on the 6502:

Code: Select all

 ; Load (SP+4)
 tsx
 lda $0104,x
Of course, this doesn't support $01ff->0100 wrapping as PHA/PLA would, but that's usually a stack underflow anyway.
Post Reply