
Site Search
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.
001 | 0000 | ORG 0 | ||
---|---|---|---|---|
002 | 0000 | 7455 | MOV A,#55H | ;Load accumulator A with 55H |
003 | 0002 | F590 | MOV P1,A | ;Send 55H to Port 1 |
004 | 0004 | 120300 | LCALL DELAY | ;Time delay |
005 | 0007 | 74AA | MOV A,#0AAH | ;Load accumulator A with AAH |
006 | 0009 | F590 | MOV P1,A | ;Send AAH to port 1 |
007 | 000B | 120300 | LCALL DELAY | |
008 | 000E | 80F0 | SJMP BACK | ;Keep doing this repeatedly |
009 | 0010 | |||
010 | 0010 | ;----This is the delay subroutine | ||
011 | 0300 | ORG 300H | ||
012 | 0300 | DELAY: | ||
013 | 0300 | 7DFF | MOV R5,#0FFH | ;Put 0FFH in R5 |
014 | 0302 | DDFE | AGAIN:DJNZ R5,AGAIN | ;Stay here |
015 | 0304 | 22 | RET | ;Return to caller |
016 | 0305 | 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 | |
---|---|
09 | 00 |
08 | 07 |
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.
01 | 0000 | ORG 0 | ||
---|---|---|---|---|
02 | 0000 | 7455 | BACK: MOV A,#55H | ;Load accumulator with 55H |
03 | 0002 | F590 | MOV P1,A | ;Send 55H to Port 1 |
04 | 0004 | 7C99 | MOV R4,#88H | |
05 | 0006 | 7D67 | MOV R5,#57H | |
06 | 0008 | 120300 | LCALL DELAY | ;Time delay |
07 | 000B | 74AA | MOV A,#0AAH | ;Load accumulator with AA |
08 | 000D | F590 | MOV P1,A | ;Send AAH to Port 1 |
09 | 000F | 120300 | LCALL DELAY | |
10 | 0012 | 80EC | SJMP BACK | ;Keep doing this |
11 | 0014 | ;---this is the delay subroutine | ||
12 | 0300 | ORG 300H | ||
13 | 0300 | C004 | DELAY:PUSH 4 | ;PUSH R4 |
14 | 0302 | C005 | PUSH 5 | ;PUSH R5 |
15 | 0304 | 7CFF | MOV R4,#0FFH | ;R4=FFH |
16 | 0306 | 7DFF | NEXT: MOV R5,#0FFH | ;R5=255 |
17 | 0308 | DDFE | AGAIN:DJNZ R5,AGAIN | |
18 | 030A | DCFA | DJNZ R4,NEXT | |
19 | 030C | D005 | POP 5 | ;POP into R5 |
20 | 030E | D004 | POP 4 | ;POP into R4 |
21 | 0310 | 22 | RET | ;Return to caller |
22 | 0311 | END | ;End of asm file |
Answer:
The stack frame is given below:
After the first LCALL | Byte | Remarks |
---|---|---|
0B | ||
0A | ||
09 | 00 | Program counter Hight Byte [PCH] |
08 | 0B | Program counter Low Byte [PCL] |
After PUSH 4 | ||
---|---|---|
0B | ||
0A | 88 | R4 |
09 | 00 | Program counter Hight Byte [PCH] |
08 | 0B | Program counter Low Byte [PCH] |
After PUSH 5 | ||
---|---|---|
0B | 57 | R5 |
0A | 88 | R4 |
09 | 00 | Program counter Hight Byte [PCH] |
08 | 0B | Program 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.