In TASM, labels that start with the current local label (which defaults to _ underscore) are only directly accessible by name within the current module. For example:

_moduleless: .equ 3

.module Renderer

    ld b, 64
    ld a, b
    call render_row
    djnz _loop
.module AI

    ld b, 32
    ld a, b
    call update_single_monster
    djnz _loop

The _loop labels are not confused because they are only declared in the local module's scope thanks to the leading underscore. They are, in fact, treated as Renderer._loop and AI._loop - so if I wanted to be very strange and jump into the rendering loop from my AI loop I could change the djnz instruction to djnz Renderer._loop. A label defined outside a module is accessible via noname - so in the above, I have noname._moduleless.

Brass extends the module idea significantly. Rather than a simple bunch of root-level modules, Brass allows you to nest modules inside eachother. This functionality cannot be added transparently as it would break TASM-style modules, so you need to specify .nestmodules before you can use these modules.

The directive .local forces all subsequent labels to be local to their module. The directive .global forces them to the global scope, and takes priority over any local label settings (the two directives are not direct opposites).

.module Animals

    .module Cat
        Legs = 4

    .echo "Humans have ", Human.Legs, " legs.\n"

    .module Human
        Legs = 2
        .module Brother
            Age = 17
            .echo "My sister is ", Animals.Human.Sister.Age, " years old.\n"
        .module Sister
            Age = 21
                Arms = 2

    .module Spider
        Legs = 8
        .echo "A spider has ", Legs, " legs.\n"


.echo "Cats have ", Animals.Cat.Legs, " legs.\n"
.echo "My brother is ", Animals.Human.Brother.Age, " years old.\n"
.echo "My sister has ", Arms, " arms (global!)\n"

Note how Arms is globally accessible, even though it is declared deep in the module Animals.Human.Sister.