Skip to content

Engineering Xpert

We Simplify Engineering

Menu
  • Home
  • About
  • Contact
  • MATLAB
  • PIC Microcontroller
Menu
CALL RCALL and RETURN Instructions for PIC Microcontroller

CALL RCALL and RETURN Instructions for PIC Microcontroller

Posted on May 27, 2022May 27, 2022 by Aamir Javed

This post describes CALL RCALL and RETURN Instructions for PIC Microcontroller with examples. CALL and RCALL instructions are used to call subroutines. RETURN instruction is used to return from a subroutine.

Subroutines are used when same piece of code is required to be used multiple times in a program. Writing this piece of code as a subroutine allows us to call it as many times as we want. without writing the code again. This saves code memory, since the code is written only once and merely “called” multiple times. The difference between unconditional branch instructions and subroutines is that the subroutines can return after execution, using RETURN instruction, to the instruction written after from where they are called. Unconditional branch instructions have no such option.

Note: For this tutorial I am using MPLAB X v5.0 but you can use any version upto v5.35. Version 5.35 is last version that included MPASM i.e. the assembler we require to compile the assembly code used in this tutorial. Code given here may not work for later versions.

RCALL: Relative Call

Syntax: RCALL label

Length of the Instruction: 2 bytes

Instruction Cycles: 2 cycles are required since the previously fetched instruction is discarded and new instruction from target address must be fetched before execution.

Instruction Encoding: 1101 1nnn nnnn nnnn

Updated Flags: None

Target Address: The target label is represented by an 11-bit relative address n in the opcode. Target address, i.e. the new value of PC where the code jumps, is calculated by adding 2n to the current value of program counter PC.

Target Address = New PC = Current PC + 2n

Description: RCALL instruction calls a subroutine and jumps to the target address / label. First the return address (i.e. the address of the instruction immediately after the RCALL) is saved by pushing it onto the stack. Then the target address is calculated and the new target address is loaded into the PC.

RCALL instruction is a short call

RCALL instruction is a short call and the target address, i.e. the new value of PC must be within 2048 bytes of the current value of the program counter (PC).

The second byte n of the instruction is a relative address. Relative address can be negative or positive. Positive address means that the code jumps forward i.e. after current PC. If the address is negative then the code jumps backwards i.e. before current PC. Target address can be calculated using

Target Address = New PC = Current PC + 2n

The relative address n is represented by 11-bits. The largest -ve relative address can be -1024, and the largest +ve relative address can be +1023. As a result, the target address can be a maximum of 2048 bytes behind the current program counter, and a maximum of 2044 bytes forward from the current program counter.

Note: PC points to the next instruction (after the conditional branch) while calculating the target address. PC is always ahead since it is used to fetch the next instruction.

RETURN: Return from Subroutine

Syntax: RETURN {s}

Length of the Instruction: 2 bytes

Instruction Cycles: 2 cycles are required since the previously fetched instruction is discarded and new instruction from return address must be fetched before execution.

Instruction Encoding: 0000 0000 0001 001s

Updated Flags: None

Return Address: The return address is loaded into PC by popping from the stack.

Shadow Registers: If s = 1, the contents of shadow registers WS, STATUSS and BSRS, are loaded into W, STATUS and BSR registers respectively. If s = 0, the W, STATUS and BSR registers are not updated. Default is s = 0.

Description: RETURN instruction causes a return from subroutine to the return address (i.e. the address of the instruction immediately after the CALL / RCALL). The return address is loaded into the PC by popping the stack.

RCALL & RETURN Example:

The following code that toggles all pins of PORTC after every 250 msecs. RCALL instruction is used to call a subroutine called DELAY_250MSEC. DELAY_250MSEC contains a nested loop generates a delay of 250 msec. RETURN instruction is written as the end, to allow return from the subroutine.

    CLRF  TRISC	    ; Make PORTC an output by writing 0's to all bits of TRISC
    MOVLW 0x55	    ; Load a value into WREG
    MOVWF PORTC	    ; Initialize PORTC by copying WREG to PORTC SFR
    
BACK
    RCALL DELAY_250MSEC	    ; RCALL delay subroutine
    COMF PORTC		    ; Toggle all pins of PORTC
    BRA BACK		    ; Infinite loop
    
    
; Delay SUBROUTINE to generate a delay of 250 msecs
 
R1 EQU 0x1	    ; Inner Loop Counter for DELAY_MSEC
R2 EQU 0x2	    ; Main Loop Counter for DELAY_MSEC
 
DELAY_250MSEC
    MOVLW D'250'
    MOVWF R2	
L_1	; MAIN loop
    MOVLW D'199'
    MOVWF R1
L_2	; inner loop
    NOP
    NOP
    DECF R1, F
    BNZ L_2	
    DECF R2, F
    BNZ L_1	
    RETURN

RCALL instruction can be used here, since the subroutine comes soon after the main loop of the program, and it is within 2048 bytes of the current PC. CALL instruction can also be used here, since it can jump to any where in PIC code ROM space. However, RCALL should be preferred as it requires 2 bytes instead of 4 bytes in ROM.

CALL: Subroutine Call

Syntax: CALL label {,s}

Length of the Instruction: 4 bytes

Instruction Cycles: 2 cycles are required since the previously fetched instruction is discarded and new instruction from target address must be fetched before execution.

Instruction Encoding: 1110 110s kkkk kkkk 1111 kkkk kkkk kkkk

Updated Flags: None

Target Address: The target label is represented by a 20-bit absolute address k in the opcode. Target address, i.e. the new value of PC where the code jumps, is 2k.

Target Address = New PC = 2k

Shadow Registers: If s = 1, the contents of register W, STATUS and BSR, are pushed into WS, STATUSS and BSRS shadow registers respectively. If s = 0, the WS, STATUSS and BSRS registers are not updated. Default is s = 0.

Description: CALL instruction calls a subroutine and jumps to the target address / label. First the return address (i.e. the address of the instruction immediately after the CALL) is saved by pushing it onto the stack. Optionally, the W, STATUS and BSR registers are pushed into their respective shadow registers. Then the target address is calculated and the new target address is loaded into the PC.

CALL instruction is a long call

CALL instruction is a long call that can jump to any memory address of the 2M code space of PIC18 microcontroller. Target address i.e. the new 21-bit value of PC where the code jumps, is 2k.

Note: PC points to the next instruction (after the conditional branch) while calculating the target address. PC is always ahead since it is used to fetch the next instruction.

CALL & RETURN Example:

The following code that toggles all pins of PORTC after every 250 msecs. CALL instruction is used to call a subroutine called DELAY_250MSEC. DELAY_250MSEC contains a nested loop generates a delay of 250 msec.

    CLRF  TRISC	    ; Make PORTC an output by writing 0's to all bits of TRISC
    MOVLW 0x55	    ; Load a value into WREG
    MOVWF PORTC	    ; Initialize PORTC by copying WREG to PORTC SFR
    
BACK
    CALL DELAY_250MSEC	    ; CALL delay subroutine
    COMF PORTC		    ; Toggle all pins of PORTC
    BRA BACK		    ; Infinite loop
    
ORG 0F00H
    
    
; Delay SUBROUTINE to generate a delay of 250 msecs
 
R1 EQU 0x1	    ; Inner Loop Counter for DELAY_MSEC
R2 EQU 0x2	    ; Main Loop Counter for DELAY_MSEC
 
DELAY_250MSEC
    MOVLW D'250'
    MOVWF R2	
L_1	; MAIN loop
    MOVLW D'199'
    MOVWF R1
L_2	; inner loop
    NOP
    NOP
    DECF R1, F
    BNZ L_2	
    DECF R2, F
    BNZ L_1	
    RETURN  

Using ORG directive, the subroutine code is placed far from the main loop, at ROM address 0xF00. It means that the subroutine is more than 2048 bytes away from the previous PC. RCALL instruction cannot be used here, so CALL instruction must be used. If you try to use RCALL instruction then MPLAB will fail to assemble the code and it will throw an error “Symbol ‘DELAY_250MSEC‘ out of range of relative branch instruction”.

Conclusion

CALL, RCALL and RETURN instructions for PIC microcontroller are used when working with subroutines. CALL instruction must be used to call the subroutine when it is more than 2048 bytes away from the previous PC. When the subroutine is within 2048 bytes of the previous PC, we can use either of them. However, RCALL should be preferred as it requires 2 bytes instead of 4 bytes in ROM. The subroutine must end with a RETURN instruction to enable the code to “return” and continue onward from where it was called.

Latest Posts

  • MOVF and MOVFF Instructions for PIC Microcontroller
  • MOVLW and MOVWF Instructions for PIC Microcontroller
  • CALL RCALL and RETURN Instructions for PIC Microcontroller
  • BRA and GOTO Instructions for PIC Microcontroller
  • INCFSZ and INFSNZ Instructions for PIC Microcontroller

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Recent Posts

  • MOVF and MOVFF Instructions for PIC Microcontroller
  • MOVLW and MOVWF Instructions for PIC Microcontroller
  • CALL RCALL and RETURN Instructions for PIC Microcontroller
  • BRA and GOTO Instructions for PIC Microcontroller
  • INCFSZ and INFSNZ Instructions for PIC Microcontroller

Categories

  • Electric Circuits
  • How To
  • MATLAB
  • MPLAB X
  • PIC18
  • PIC18 Assembly
  • PIC18 C
  • Proteus
  • STM32
  • STM32Cube IDE
  • STM32F3 Discovery Kit

About

We post tutorials and guides related to a variety of topics like MATLAB, PIC18 Microcontrollers, Electric Circuits, Digital Logic Design, Arduino, Raspberry Pi, STM32

© 2023 Engineering Xpert | Powered by Superbs Personal Blog theme