It is currently Fri Oct 20, 2017 12:55 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 45 posts ]  Go to page 1, 2, 3  Next
Author Message
PostPosted: Wed May 04, 2016 1:31 pm 
Offline
User avatar

Joined: Sat Sep 07, 2013 2:59 pm
Posts: 1402
One thing that I have seen in various codes is the use of unnamed labels.

I haven't used them myself, but from what I've seen, I assume that : is an unnamed label and that JMP :+ means "go down to the next unnamed label", JMP :- means "go up to the next unnamed label" and JMP :++ means "go down until you are at the second unnamed label that you encounter".

My question is: Why do people use this? Is there any advantage over named labels?

I like the idea of local labels very much, giving me the chance to use names like @end and @loop in multiple functions.
But I've never seen the appeal of unnamed labels.

In fact, I only see disadvantages:

1. When reading the code, you cannot readily see where the jump goes to. You have to take the number of pluses or minuses and then count through all the colons to check where you end up.
With named labels, it is much clearer where the jump goes to. Especially in text editors like Notepad++ where I just need to mark the name and then the other occurences of the name get a colored background.

2. The unnamed labels are error-prone.
Remove a label and forget to remove the references: Your code has just gotten a bug.
Remove a label and forget to update the references that don't even have to do with it, but that point to other unnamed level: Your code has just gotten a bug.
Reorder code (switching around two sections that each start with a label) and forget to switch the number of pluses and minuses elsewhere in the code: Your code has just gotten a bug.
But remove a named label and forget to remove the references and the compiler will give you an error message.
And switch around two code sections that start with named labels and the rest of the code can still remain as it is.

So, where's the advantage? What's the reason to ever use unnamed labels?

_________________
Available now: My game "City Trouble".
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg


Last edited by DRW on Wed May 04, 2016 1:57 pm, edited 1 time in total.

Top
 Profile  
 
PostPosted: Wed May 04, 2016 1:43 pm 
Offline
User avatar

Joined: Fri Oct 14, 2011 1:09 am
Posts: 248
The syntax of : which is referred with :- or :+ is an idiom of CA65. I actually much prefer the way XA65 does it, i.e. the label is -, --, or --- if it is only entered with backwards branches, and +, ++, +++ if forward branches, and the same label occurs in both the label and the branch instruction. They can also be nested; the longer the sequence minuses or pluses, the larger its scope is.

As for why? It allows brevity. You don't need to assign a name for every single thing you do. Sometimes a loop is just a loop. An "if" is just an "if". No need to attach sentiment and deeper meaning to it. The short label is just the means to the end; it is minimal so as not to distract the viewer from the actual topic at hand. The same reason why { and } are just single characters in C. Compared to using a goto with a label, the same potential problems with error propensity arise, although the mandatory pairing helps mitigate it a little.


Last edited by Bisqwit on Wed May 04, 2016 1:46 pm, edited 1 time in total.

Top
 Profile  
 
PostPosted: Wed May 04, 2016 1:46 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19110
Location: NE Indiana, USA (NTSC)
In my code, I don't use more than one + or -, and the target is almost always within ten lines. It might be a really tight loop:
Code:
  ; Wait for NMI handler to signal vertical blanking
  lda nmis
  :
    cmp nmis
    beq :-

Code:
  ; Load initial palette
  ldx #$3F
  stx PPUADDR
  ldx #$00
  stx PPUADDR
  :
    lda palette,x
    sta PPUDATA
    inx
    cpx #32
    bcc :-


Or an addition of a 16-bit signed velocity to a 24-bit position, to skip over adjustment of the most significant byte if not needed:
Code:
  ; Add velocity to position
  clc
  lda actor_xvel_sub,x
  adc actor_x_sub,x
  sta actor_x_sub,x
  lda actor_xvel,x
  bpl :+
    dec actor_x_hi,x
  :
  adc actor_x,x
  bcc :+
    inc actor_x_hi,x
  :
  sta actor_x,x

For longer branches than about a half dozen lines, I come up with a name for the target that reflects what the code does. For example, a forward branch skipping over something might be called bcc not_in_wall or beq not_start. But these are cases where what the code does is self-evident from the variable names.


Top
 Profile  
 
PostPosted: Wed May 04, 2016 2:09 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10064
Location: Rio de Janeiro - Brazil
DRW wrote:
I assume that : is an unnamed label and that JMP :+ means "go down to the next unnamed label", JMP :- means "go up to the next unnamed label" and JMP :++ means "go down until you are at the second unnamed label that you encounter".

This is ca65's notation, yes.

Quote:
My question is: Why do people use this? Is there any advantage over named labels?

You don't have to think of names for EVERY. SINGLE. BRANCH.

Quote:
1. When reading the code, you cannot readily see where the jump goes to. You have to take the number of pluses or minuses and then count through all the colons to check where you end up.

I don't know how other people use their unnamed labels, but I only use them for really short jumps. As for having to count the number of pluses/minuses, that's the one annoying thing about ca65's approach to unnamed labels IMO. If you're editing a block of code and need to add more unnamed labels, you have to look for all nearby references to unnamed labels and fix the ones that need fixing. In these situations I tend to use unique labels (not necessarily meaningful, sometimes I just hit random keys) while editing, and only change everything to unnamed labels once that part of the logic is done. This is the reason I like ASM6's approach better.

Quote:
Remove a label and forget to remove the references: Your code has just gotten a bug.
Remove a label and forget to update the references that don't even have to do with it, but that point to other unnamed level: Your code has just gotten a bug.
Reorder code (switching around two sections that each start with a label) and forget to switch the number of pluses and minuses elsewhere in the code: Your code has just gotten a bug.
But remove a named label and forget to remove the references and the compiler will give you an error message.

True. This is the main drawback of ca65's unnamed labels.

Quote:
So, where's the advantage? What's the reason to ever use unnamed labels?

Like I said, in small sections of code or small loops where all decisions are straightforward and don't need any explanation. I find some operations more readable without a big label splitting up the code. For example, I have this code to hide all unused sprites:

Code:
   ;hide all unused sprites
   ldy Video::AvailableSprites
   beq Return
   ldx Video::NextBackSprite
   lda #Video::HIDDEN_SPRITE_Y
   bne :++
:   dex
   dex
   dex
   dex
:   sta Video::OAMBuffer+Video::SPRITE_Y, x
   dey
   bne :--

The comment at the top describes what the entire block of code does, and it's a very small and simple piece of logic that doesn't require further explanations, so I think it's more readable to have the entire operation tightly packed in a small block.


Top
 Profile  
 
PostPosted: Wed May 04, 2016 2:39 pm 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2962
Location: Tampere, Finland
I don't use them personally. I don't even use local (@) labels that often (out of habit), since I tend to wrap most of my functions in .proc blocks, and sometimes also use .scope blocks within the .proc.

Never really had a problem coming up with label names.

Personally, I would do something like this for tokumaru's snippet:
Code:
    ;hide all unused sprites
    ldy Video::AvailableSprites
    beq Return
    ldx Video::NextBackSprite
    lda #Video::HIDDEN_SPRITE_Y
    bne startLoop
    loop:
        dex
        dex
        dex
        dex
    startLoop:
        sta Video::OAMBuffer+Video::SPRITE_Y, x
        dey
    bne loop

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi


Top
 Profile  
 
PostPosted: Wed May 04, 2016 2:56 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10064
Location: Rio de Janeiro - Brazil
thefox wrote:
Personally, I would do something like this for tokumaru's snippet:

I kinda feel like "loop" and "startLoop" break the flow of the logic. I can visualize it better without the names. I also don't like indenting assembly code... I think it looks weird with labels, and since the flow of assembly is less restricted, sometimes the logic doesn't map well to indented blocks.

I make heavy use of .scope blocks (not .proc though - I use my own version that allows for the entry point to be in places other than the very top), so I too don't feel the need to use local (@) labels.


Top
 Profile  
 
PostPosted: Wed May 04, 2016 2:59 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3192
Location: Mountain View, CA, USA
DRW wrote:
My question is: Why do people use this? Is there any advantage over named labels?

Convenience, specifically for simple/obvious loops that tend to be small. Anything substantially complex (I would say more than two unnamed labels), IMO, warrants use of an actual label. The code snippets tepples provided (esp. the first two) are good working examples of where use of an unnamed label still makes for legible ease-of-understanding code. The bright side to unnamed labels is: you don't have to use them. :-) I try not to get hung up on things like this -- I'd rather be writing actual code than pontificating over the pros/cons of optional assembler features.


Top
 Profile  
 
PostPosted: Wed May 04, 2016 3:35 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5726
Location: Canada
I use them constantly. I like the way they look, they're quick to type. I think for simple branches they're easier to read than something like @loop.

I use :++ less often, and rarely use :+++, but I don't find them very error-prone, in my experience. Part of it is that I use a style with indentation to indicate structure, so it's clear to me where it's going. My : usage is similar to how I would use C's { and } with control structures. Another part of it is that I don't use them if I think the branching is complicated, or over a long span; this is exclusively for short blocks of code.

One thing you might not know is that ca65 will generate an error if there is no reference to an unnamed label. This catches a lot of the potential errors when making code revisions around these things.


Top
 Profile  
 
PostPosted: Wed May 04, 2016 4:55 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19110
Location: NE Indiana, USA (NTSC)
But ca65 also doesn't scope unnamed labels. I can define one in one .proc and accidentally refer to it in another. Usually the result is a "Range error", but sometimes the result is a silent successful assembly of a defective program.


Top
 Profile  
 
PostPosted: Wed May 04, 2016 5:47 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5726
Location: Canada
Yes, there are always potential errors, but I think I've only had to debug an erroneous : maybe 2 times in the past year, whereas I think the assembler has caught unreferenced unnamed label errors maybe 10 times? They way I work, the kind of mistakes I make with them tend to produce that assembly error more often than not.

Your mileage may vary. I don't find they cause me much grief, compared to a lot of other things.

I have thousands of unnamed labels in the code for my current project; that's thousands of times I didn't have to think of or read a name. ;)


Top
 Profile  
 
PostPosted: Wed May 04, 2016 11:32 pm 
Offline

Joined: Thu Aug 12, 2010 3:43 am
Posts: 1589
Yeah, not having to think names for all those dumb branches is probably the main reason why unnamed labels exist.

One other big problem I don't see mentioned is that a lot of assemblers seem to simply not support local labels properly (or at all), period, and when they do they may disagree on the syntax, while unnamed labels seem to have better support and tend to be mostly the same across tools. No idea how bad it is on the 6502, I know it can easily become hell with other architectures though.


Top
 Profile  
 
PostPosted: Thu May 05, 2016 2:07 am 
Offline
Formerly WheelInventor

Joined: Thu Apr 14, 2016 2:55 am
Posts: 906
Location: Gothenburg, Sweden
Also, for disassemby, i think the use is reasonable until you've figured out what stuff is for for sure.

_________________
http://www.frankengraphics.com - personal NES blog


Top
 Profile  
 
PostPosted: Thu May 05, 2016 2:28 am 
Offline

Joined: Mon Sep 27, 2004 2:57 pm
Posts: 1248
Instead of anonymous labels, DASM has two types of temporary labels: the traditional kind whose scope is defined by a pseudo-op, and a super-temporary kind whose scope is the next non-temporary label. The latter kind are like anonymous labels in that the scope is (meant to be) very small, and you can drop one in without disturbing the scope of anything else. It's not any better or worse than CA65's anonymous labels, just different.


Top
 Profile  
 
PostPosted: Thu May 05, 2016 2:55 am 
Offline

Joined: Tue May 28, 2013 5:49 am
Posts: 804
Location: Sweden
The author of the CA65 help file doesn't seem to like them.

Like everyone else here, I use them only for very short jumps in smaller routines. But quite rarely, and in all cases I have used them I think they could be replaced by a local label with very simple general names like @loop, @skip or @exit, and still be equally readable. Generally I prefer to have names on things, but if it's a really small routine it's fine either way.

The only advantages over local labels I can think of is that they are fast to type, fast to read and doesn't require any global labels around them.


Top
 Profile  
 
PostPosted: Thu May 05, 2016 3:09 am 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2962
Location: Tampere, Finland
tokumaru wrote:
thefox wrote:
Personally, I would do something like this for tokumaru's snippet:

I kinda feel like "loop" and "startLoop" break the flow of the logic. I can visualize it better without the names. I also don't like indenting assembly code... I think it looks weird with labels, and since the flow of assembly is less restricted, sometimes the logic doesn't map well to indented blocks.

It probably comes down to what each of us is used to. It's true that not all assembly code can be indented properly, but most of the common structures can (loop back, branch forward on a negated condition, ...).

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 45 posts ]  Go to page 1, 2, 3  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: Bing [Bot], Google Adsense [Bot] and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group