简体   繁体   中英

MPLAB/XC8 can't jump in ASM?

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 - CALL , GOTO , BNC , 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: BC $+4 skips the next line.

An example of what does not work is this:

#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);
}

Now, this may not work overall, and I am begging 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.

As soon as waitUS(6) is called, the PC jumps from - in my case - 0x7C96 to 0x52 . Swapping the C call out for MOVLW 6; CALL _waitUS MOVLW 6; CALL _waitUS breaks in exactly the same way.

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.

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?

Edit: Having discovered the program memory view, I was able to get a better idea of what it's doing. The compiler does know where the functions are, and it is trying to jump to the right location. Apparently, CALL just doesn't know where it's going.

Example: Address 0x7C92 contains CALL 0x2044, 0 . That is precisely what it ought to, that is where the desired function starts. However, upon running this instruction, PC is altered to 0x205E , missing half of the function.

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 0x205E . Unfortunately, it seems any change alters where its unpredictable jumping will land, and it then landed at 0x2086 instead.

Incidentally, when it starts running at random places, it will often run across a GOTO - and it will jump to the specified location as intended. This only works within the same function, as trying to use GOTO instead of CALL ends up in the same incorrect location, despite what the compiled result demands.

the .pdf document at: 
<http://ww1.microchip.com/downloads/en/DeviceDoc/33014K.pdf>

has many examples on how to code the PIC18. 
Here is one such example:

RST CODE 0x0 ;The code section named RST
    ;is placed at program memory
    ;location 0x0. The next two
    ;instructions are placed in
    ;code section RST.
    pagesel start ;Jumps to the location labelled
    goto start ;’start’.

PGM CODE ;This is the beginning of the
    ;code section named PGM. It is
    ;a relocatable code section
    ;since no absolute address is
    ;given along with directive CODE.
start
    movlw D'10'
    movwf delay_value
    xorlw 0x80
    call delay
    goto start
    end 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM