SECTION - II CALL INSTRUCTIONS IN 8051 MICROCONTROLLER

SECTION - II CALL INSTRUCTIONS IN 8051 MICROCONTROLLER

CALL instruction is another control transfer instruction. CALL instruction is used to call a subroutine. Need to performed the tasks frequently subroutines are used. Using a subroutine make a program more structured and helps in reducing memory space. There are two instructions for CALL in the 8051 programming. LCALL [Long Call] and ACALL [Absolute call].

LCALL [Long Call]:

LCALL is a 3-byte instruction. This first byte is the opcode and the second and third bytes are used for the address for the target subroutine. Anywhere Within the 64K byte address space of the 8051, LCALL can be used to call subroutines. The 8051 microcontroller knows where to come back to, it automatically saves on the stack the address of the instruction immediately below the LCALL. When a subroutine is called, the control is transfered to that subroutine, and the processor saves the program counter [PC] on the stack and begins to fetch instructions from the new location. After finishing execution of the subroutine, the instruction RET [Return] transfers control back to the caller. RET [Return] needs by every subroutine as the last instruction.

Example # 1:

Lets write a program to toggle all the bits of port 1 by sending it the values 55H and AAH continuously. Put a time delay between each issuing of data to port 1.

Answer:

ORG 0 
BACK: MOV A,#55H;Load A with 55H
MOV P2,A;Send 55H to Port 2
LCALL DELAY;Time Delay
MOV A,#0AAH;Load accumulator with AAH [in hex]
MOV P2,A;Send AAH to port 2
LCALL DELAY;Time Delay
SJMP BACK;Keep doing this indefinitely
;---This is the delay subroutine  
ORG 300H;Put the time delay at address 300H
DELAY: MOV R4,#0FFH;R4=255 [FF in hex], the counter
AGAIN: DJNZ R5,AGAIN;Stay here until R4 becomes 0
RET;Return to Caller [when R4=0]
END;End of asm file

In the above example, following point should be noted.

  • When the first "LCALL DELAY" is executed, the address of the instruction right below it , "MOV A,#0AAH", is pushed onto the stack, and the 8051 starts to execute instructions at address 300H.
  • In the DELAY subroutine, first the counter R4 is set to 255 [FFH in hex]. 255 means the loop will be repeated 256 times. When R4 becomes zero, control falls to the RET instruction which pops address from the stack into the program counter and resumes executing the instructions after the CALL. 
  • The amount of time delay depends on the frequency of the 8051. We can increase the time delay by using nested loop as shown below.
DELAY:;Nested Loop Delay
MOV R4,#255;Load R4=255 [FF in hex]
NEXT: MOV R5,#255;Load R5=255 [FF in Hex]
AGAIN: DJNZ R5,AGAIN;Stay here until R5 becomes zero
               DJNZ R4,NEXT;Decrement R4
SJMP NEXT;Keep loading until R5 becomes zero
RET;Return to caller when R5=0
END;End of asm file

Rewriting Example # 1 more efficiently:

Answer:

ORG 0 
MOV A,#55H;Load accumulator A with 55H
BACK: MOV P1,A;Issue value in register accumulator A to Port 1
ACALL DELAY;time delay
CPL A;Complement register A i.e 55H becomes AAH
SJMP BACK;Keep doing this indefinitely
 ;----------this is the delay subroutine
DELAY: MOV R5,#0FFH;R5=255 [FF in Hex], the counter
AGAIN: DJNZ R5,AGAIN;Stay here until R5 becomes 0
RET;Return to caller
END;End of asm file

The register accumulator A is loaded with 55H. By complementing 55H, we have AAH. By complementing AAH, we have 55H. In binary 55H=01010101. In binary AAH=10101010. So by complementing 01010101[55H] we have 10101010[AAH] and by complementing 10101010[AAH] we have again 01010101[55H].

Importance of Stack and the CALL Instruction:

To understand the importance of stack in microcontroller, lets examine the contents of the stack in microcontroller in Example # 1. Lets examine the stack contents after the execution of the first LCALL below.

0010000 ORG 0 
00200007455MOV A,#55H;Load accumulator A with 55H
0030002F590MOV P1,A;Send 55H to Port 1
0040004120300LCALL DELAY;Time delay
005000774AAMOV A,#0AAH;Load accumulator A with AAH
0060009F590MOV P1,A;Send AAH to port 1
007000B120300LCALL DELAY 
008000E80F0SJMP BACK;Keep doing this repeatedly
0090010   
0100010  ;----This is the delay subroutine
0110300 ORG 300H 
0120300 DELAY: 
01303007DFFMOV R5,#0FFH;Put 0FFH in R5
0140302DDFEAGAIN:DJNZ R5,AGAIN;Stay here
015030422RET;Return to caller
0160305 END;End of asm file

When the first LCALL is executed, the address of the instruction "MOV A,#0AAH" is saved on the stack. The low byte goes first and the high byte is last. The last instruction of the called instruction must be a RET instruction which directs the CPU to POP the top bytes of the stack into the program counter [PC] and resume executing at address 07. The stack frame after the first LCALL is given below.

0A 
0900
0807
Stack Pointer = 09 

PUSH and POP instructions in subroutines:

The stack keeps track of where the CPU should return after completing the cubroutine, where ever a subroutine is called. The number of PUSH and POP instructions must always match in any called subroutine. For every PUSH instruction executed, there is a POP instruction to be executed also.

Example # 2:

Lets analyze the stack for the first LCALL instruction.

010000 ORG 0 
0200007455BACK: MOV A,#55H;Load accumulator with 55H
030002F590MOV P1,A;Send 55H to Port 1
0400047C99MOV R4,#88H 
0500067D67MOV R5,#57H 
060008120300LCALL DELAY;Time delay
07000B74AAMOV A,#0AAH;Load accumulator with AA
08000DF590MOV P1,A;Send AAH to Port 1
09000F120300LCALL DELAY 
10001280ECSJMP BACK;Keep doing this
110014  ;---this is the delay subroutine
120300 ORG 300H 
130300C004DELAY:PUSH 4;PUSH R4
140302C005PUSH 5;PUSH R5
1503047CFFMOV R4,#0FFH;R4=FFH
1603067DFFNEXT: MOV R5,#0FFH;R5=255
170308DDFEAGAIN:DJNZ R5,AGAIN 
18030ADCFADJNZ R4,NEXT 
19030CD005POP 5;POP into R5
20030ED004POP 4;POP into R4
21031022RET;Return to caller
220311 END;End of asm file

Answer:

The stack frame is given below:

After the first LCALLByteRemarks
0B  
0A  
0900Program counter Hight Byte [PCH]
080BProgram counter Low Byte [PCL]
After PUSH 4  
0B  
0A88R4
0900Program counter Hight Byte [PCH]
080BProgram counter Low Byte [PCH]
After PUSH 5  
0B57R5
0A88R4
0900Program counter Hight Byte [PCH]
080BProgram counter Low Byte [PCH]

Assembly Main Program that Calls Subroutines:

By using LCALL instruction, the target address of the subroutine can be anywhere within the 64K bytes memory space of the 8051. This is not the case for the other call instruction i.e ACALL.

;MAIN program calling subroutines 
ORG 0 
MAIN: LCALL subroutine_1 
             LCALL subroutine_2 
             LCALL subroutine_3 
HERE: SJMP HERE 
 ;---------------------------------End of MAIN
; 
subroutine_1: .... 
RET 
 ;---------------------------------End of subroutine 1
; 
subroutine_2: .... 
RET 
 ;---------------------------------End of subroutine 2
subroutine_3: .... 
RET 
 ;---------------------------------End of subroutine 3
END;End of asm file

What is Absolute Call in 8051 [ACALL]:

ACALL is a 2 byte instruction as compared to LCALL. LCALL is a 3 byte instruction. The target address of the subroutine must be within 2K bytes address because only 11 bits of the 2 bytes are used for the address.  There is no difference between ACALL and LCALL in terms of saving a program counter on the stack or the function of the RET instruction. The only difference is that the target address for LCALL can be anywhere within the 64K byte address space of the 8051. The target address of the ACALL must be within 2K byte range. 8051 marketed by different companies, on-chip ROM is as low as 1K bytes. In this case, the use of ACALL instead of LCALL can save the number of bytes of program ROM space.

More From Iamtechnical.com

Advertisement: