title: MPLAB/XC8 can't jump in ASM?
body: <p>I have a project for the PIC18F25K50 of mixed C and Assembly; most of what I want to do I can easily manage (and must for efficiency) in Assembly, but some parts where I care more about ease of development use C. I actually have a couple of these, and I keep encountering the same issue: I can't use ASM to jump to a label. Every single function to jump - <code>CALL</code>, <code>GOTO</code>, <code>BNC</code>, and so on - will fail if given a label, setting PC to some random-but-consistent value where there are no instructions, causing the program to hang. Using an address works fine: <code>BC $+4</code> skips the next line.</p>
  
  <p>An example of what does not work is this:</p>
  
  <pre><code>#asm
  _waitUS:
      GLOBAL  _waitUS
  waitLoop:
      //12 cycles = 1 microsecond:
      NOP
      NOP
      NOP
      NOP
      NOP
      NOP
      NOP
      NOP
      NOP
      DECFSZ  WREG, F, ACCESS
      GOTO waitLoop
      RETURN
  #endasm
  
  void main() {
      //DEBUG:
      waitUS(6);
  }
  </code></pre>
  
  <p>Now, this may not work overall, and I am <strong>begging</strong> you to focus on the issue of jumping - this is still in  prototyping because I can't even get the function called. The program does compile without issue.</p>
  
  <p>As soon as <code>waitUS(6)</code> is called, the PC jumps from - in my case - <code>0x7C96</code> to <code>0x52</code>. Swapping the C call out for <code>MOVLW 6; CALL _waitUS</code> breaks in exactly the same way.</p>
  
  <p>If I strictly use C for calling/jumping (as I had to in the previous project), it works fine, and figures out where it's going.</p>
  
  <p>I've been searching for an answer to this for a few weeks now, and still haven't seen anyone else with this problem, even though every project I make (including plaintext in notepad, compiling via command line) has the exact same issue. What the heck is up with this?</p>
  
  <p><strong>Edit:</strong> Having discovered the program memory view, I was able to get a better idea of what it's doing. The compiler <em>does</em> know where the functions are, and it <em>is</em> trying to jump to the right location. Apparently, CALL just doesn't know where it's going.</p>
  
  <p>Example:
  Address <code>0x7C92</code> contains <code>CALL 0x2044, 0</code>. That is precisely what it ought to, that is where the desired function starts. However, upon running this instruction, <code>PC</code> is altered to <strong>0x205E</strong>, missing half of the function.</p>
  
  <p>Attempting to be clever, I decided to tack on several NOPs to the start of the function after its label, lining the real code up with <code>0x205E</code>. Unfortunately, it seems any change alters where its unpredictable jumping will land, and it then landed at <code>0x2086</code> instead.</p>
  
  <p>Incidentally, when it starts running at random places, it will often run across a <code>GOTO</code> - and it <em>will</em> jump to the specified location as intended. This only works within the same function, as trying to use <code>GOTO</code> instead of <code>CALL</code> ends up in the same incorrect location, despite what the compiled result demands.</p>