Menu

#3390 sm83 label in inlineasm

open
nobody
None
other
5
2022-09-01
2022-05-15
Under4Mhz
No

When compiling the below test code I get the error:

sdcc -msm83 test.c
test.asm:51: Error: undefined symbol encountered during assembly

void test( unsigned int count ) {
    if ( count == 0 ) return;
    __asm
loop:
        ret
    __endasm;
}

which processes the following assembly:

    39  ;--------------------------------------------------------
    40  ; code
    41  ;--------------------------------------------------------
    42      .area _CODE
    43  ;test.c:2: void test( unsigned int count ) {
    44  ;   ---------------------------------
    45  ; Function test
    46  ; ---------------------------------
    47  _test::
    48  ;test.c:4: if ( count == 0 ) return;
    49      ld  a, d
    50      or  a, e
    51      jr  Z, 00103$
    52  ;test.c:12: __endasm;
    53  loop:
    54      ret
    55  00103$:
    56  ;test.c:13: }
    57      ret
    58      .area _CODE
    59      .area _INITIALIZER
    60      .area _CABS (ABS)

Find files attached.

sdcc -v
SDCC : mcs51/z80/z180/r2k/r2ka/r3ka/sm83/tlcs90/ez80_z80/z80n/ds390/pic16/pic14/TININative/ds400/hc08/s08/stm8/pdk13/pdk14/pdk15/mos6502 4.2.2 #13446 (Linux)

1 Attachments

Discussion

  • Sebastian Riedel

    This is a know “bug”.
    Don’t use named labels, they don’t work when they get embedded into structures that gets translated into jumps.
    You have to use something like:

    void test( unsigned int count ) {
        if ( count == 0 ) return;
        __asm
    2$:
            ret
        __endasm;
    }
    

    “3.11.4 Use of Labels within Inline Assembler” explicitly says:

    All labels defined within inline assembler code have to be of the form nnnnn$ where nnnnn is a number less than 100

    The compiler internally uses reusable symbols for all jumps. By introducing normal named labels, you limit the scope of reusable labels. In your example are jr Z, 00103$ and 00103$: in different scopes, that’s why the assembler complains that label 00103$ is not defined.

     

    Last edit: Sebastian Riedel 2022-05-17
  • Under4Mhz

    Under4Mhz - 2022-05-18

    Thanks, I didn't realize it was an accepted limitation.

    What I understand is the asm/endasm creates a new scope and the $00103 label is within that scope, rather than the if statement's scope.

    The work around I made here is to remove the if/return statement to the calling function, and then it compiles fine. I'll avoid mixing C and asm code in the same function. While technically incorrect to use (and nicely documented), I find named labels improve the readability of my (already barely comprehensible) assembly code.

    As an aside, that link to the manual complains about it being a security risk. And that made me scared, so I didn't download it. (Too many bad experiences from my IT department, no doubt). I'm using FireFox on Ubuntu 20.04.

     
    • Sebastian Riedel

      http://sdcc.sourceforge.net/doc/sdccman.pdf is the official manual. It’s probably also included in the downloads.
      I used an anchored link directly to the chapter, which doesn’t work anyways if you don’t use the builtin PDF viewer of firefox/chrome.

      edit:
      It could be that it generates that warning because sdcc.sourceforge.net doesn’t use https, but not sure.

      edit2:
      You probably got that warning because I linked a non-https file from a https site (this ticket system). So it might work when you go directly to http://sdcc.sourceforge.net/ and click on the documentation on the left side.

       

      Last edit: Sebastian Riedel 2022-05-18
  • Maarten Brock

    Maarten Brock - 2022-05-18
    • Description has changed:

    Diff:

    --- old
    +++ new
    @@ -1,7 +1,7 @@
     When compiling the below test code I get the error:
    
     sdcc -msm83 test.c
    -test.asm:51: Error: <u> undefined symbol encountered during assembly
    +test.asm:51: Error: <u> undefined symbol encountered during assembly</u>
    
     ~~~
     void test( unsigned int count ) {
    
     
  • Maarten Brock

    Maarten Brock - 2022-05-18

    It's not the asm/endasm that makes a new scope. It's your label "loop:" that starts a new scope. And then the jump can no longer see its label. In inline asm you should only use numeric local labels and they must be below 100.

     
  • Under4Mhz

    Under4Mhz - 2022-07-10

    I wanted to add the main reason I reported this issue is this worked fine under sdcc 4.1.

    The reason I mention the documentation link issue, is that I suspect most browsers will probably complain about non-secure links and refuse to download it, so I suspect most people won't be able see to any the links you post from the manual.

     
  • Philipp Klaus Krause

    • summary: sm83 --> sm83 label in inlineasm
     

Log in to post a comment.

MongoDB Logo MongoDB