Calling assembly function from sketch

I am trying to call an assembly function from a sketch. My sketch for Arduino Uno is below.

// Define external assembly functions and global variables
extern "C" {
  void test();
  unsigned char *pu;
  unsigned char *pv;
}

void setup() {
  Serial.begin(9600);

  unsigned char u = 0;
  unsigned char v = 0;

  pu = &u;
  pv = &v;

  for (u = 0; u < 16; u++) {

    Serial.print("u = ");
    Serial.println(*pu, BIN);
    
    test();
    
    Serial.print("v = ");
    Serial.println(*pv, BIN);

  }

  return 0;

}

And my assembly file (endec.S) is below.

 .global test
 .global pu
 .global pv

 test:
    PUSH  R17
    CLR   R17
    
    LDS   R17, pu
    STS   pv, R17
    
    POP   R17
    RET

With this code, on the serial monitor I see u increments from 0 to 15, and v is the same value as u as expected. But if I add any instruction between LDS and STS (e.g. INC R17), the v seems to change to a constant independent of u. Why is that? I am using this post as my reference: https://forum.arduino.cc/index.php?topic=413151.msg2844634#msg2844634

I suspect that r16/r17 contain the surrounding variable declaration u, and r18/r19 contain the surrounding variable declaration v. Therefore there is some mess with your register usage.

If you change your .S file for this, using r0 (or r1) it should work :

 .global test
 .global pu
 .global pv

 test:
    
 ;;; use R0 or R1 for intermediate calculation
    
    lds   r0, pu ;;; or  lds 0, pu
    add   r0, 1
    sts   pv, r0
    
   
    ret

Edit : BTW your C code doesn’t compile, you can use this code instead (no return in void setup() !!!):

// Define external assembly functions and global variables
extern "C" {
  void test();
  unsigned char *pu;
  unsigned char *pv;
}

void setup() {
  Serial.begin(9600);

  unsigned char u = 0;
  unsigned char v = 0;

  pu = &u;
  pv = &v;

  for (u = 0; u < 16; u++) {

    Serial.print("u = 0b");
    Serial.println(*pu, BIN);
    
    test();
    
    Serial.print("v = 0b");
    Serial.println(*pv, BIN);

  }


}
void loop(void) {
  
}