gbdev / rgbds

Rednex Game Boy Development System - An assembly toolchain for the Nintendo Game Boy and Game Boy Color
https://rgbds.gbdev.io
MIT License
1.33k stars 175 forks source link

Anonymous labels should not be exported with `rgbasm -E` #1137

Closed Rocco-Gossmann closed 10 months ago

Rocco-Gossmann commented 1 year ago

Hello,

I'm trying to learn the ropes of rgbds and I encountered an issue regarding the "Anonymous Labels" described here: https://rgbds.gbdev.io/docs/v0.6.1/rgbasm.5#Anonymous_labels

My Project has multiple asm files, which get compiled individualy and then linked together in the end.

Everything is managed via a Makefile.

this is my main.asm

SECTION "main", ROM0[$150]

include "core/memory.inc"

cLCDC   equ  $ff40
cBGMAP0 equ  $9800 ;- 9bff   used when LCDC s bit $10 is turned off

main::
    ; Disable screen
    ld hl, cLCDC
    res 7, [hl]

    ; fill map 0 (32*32 Byte) with zeros
    fill_mem cBGMAP0, $0400, 0

    ; Enable screen
    ld hd, CLCDC
    set 7, [hl]

; main-loop
:   halt
    nop
    jr :- 

This is the core/memory.inc that main.asm includes.

/*==============================================================================
 ## fill_mem(n16 adress, n16 length, n8 fillbyte)
 Fill a number of bytes at address HL with the value stored in A
 ------------------------------------------------------------------------------
 ### Input:
   - adress:  memory adress from which to fill
   - length: number of bytes to fill
   - fillbyte: byte to fill the memory with

 ### Destroys:
   - AF
   - HL
   - BC
 ============================================================================*/
MACRO fill_mem
    ld hl, \1
    ld a, \3 
    ld bc, \2
    call _fill_BC_bytes_at_HL_with_A
ENDM

And this is the core/memory.asm that contains the actual function that gets executed when fill_mem() is called

SECTION "core.memory", ROM0

include "./utils.inc"

_fill_BC_bytes_at_HL_with_A::
    push hl
    push bc
    push af

:   check_BC_zero
    jp z, :+
        pop af
        push af

        ld [hli], a
        dec bc
    jp :-

:   pop af
    pop bc
    pop hl
    ret

Both main.asm and core/memory.asm get compiled individualy.

...
rgbasm -h -E -i./src -i./src/core -osrc/main.asm.obj src/main.asm
rgbasm -h -E -i./src -i./src/core -osrc/core/memory.asm.obj src/core/memory.asm

and then linked together

rgblink -t -oday001-clearing_the_screen.debug.gb -nday001-clearing_the_screen.sym ./src/card.asm.obj ./src/main.asm.obj ./src/core/memory.asm.obj

which then results in this lovely little error here:

error: "!0" both in ./src/core/memory.asm.obj from src/core/memory.asm(10) and in ./src/main.asm.obj from src/main.asm(17)
make: *** [Makefile:14: debug] Fehler 1
ISSOtm commented 1 year ago

Ah, I see what the problem is: since you're using rgbasm -E, the anonymous labels are exported, and this is causing a link failure.

The fix is not to export anonymous labels, regardless of that flag.

Rocco-Gossmann commented 1 year ago

Can confirm, that removing -E from the rgbasm command fixed the problem. Thanks.

Just out of curiosity, What is the point of rgbds -E ...? Labels seem to be still exported, in the linking step when setting the -n parameter. rgblink ... -n$(TARGET).sym Even if rgbds -E was not set.

ISSOtm commented 1 year ago

Imo, it serves no good purpose; but it's there, maybe for some legacy reason, and so we're keeping it to avoid breaking backwards compat.

The reason why these labels are still exported is because they are defined with ::; -E only affects labels defined with : (or local labels defined with no colons).

Rangi42 commented 10 months ago

Even without ::, I still get this error. On the other hand, without -E, there's no error, whether or not the asm uses ::.

a.asm:

SECTION "a", ROM0[$00]
fn_a:
    xor a
:   nop
    jr :-

b.asm:

SECTION "b", ROM0[$10]
fn_b:
    xor a
:   nop
    jr :-
$ rgbasm -E -o a.o a.asm
$ rgbasm -E -o b.o b.asm
$ rgblink -t -o c.gb -n c.sym a.o b.o
error: "!0" both in b.o from b.asm(5) and in a.o from a.asm(5)