
Site Search
CHAPTER #2- CALL, LOOP AND JUMP INSTRUCTIONS IN 8051
CHAPTER #2- CALL, LOOP AND JUMP INSTRUCTION IN 8051
In the sequence of instructions to be executed, it is often necessary to transfer program control to a different location. There are many instructions in the 8051 to achieve this goal. This chapter covers the control transfer instructions available in 8051 Assembly Language.
Upon completion of this chapter, you will be able to learn & apply:
- Program 8051 Assembly Language instructions using Loops
- Program 8051 Assembly Language conditional jump instructions
- Explain conditions that determine each conditional jump instruction`
- Program long jump instructions for unconditional jumps
- Program short jump instructions for unconditional short jumps
- Calculate the target addresses for jump instructions
- Program 8051 subroutines
- Describe precautions in using the stack in subroutines
- Discuss crystal frequency versus machine cycle
- Code 8051 programs to generate a time delay
SECTION - I: JUMP AND LOOP INSTRUCTIONS:
The various types of control transfer instructions in assembly language include conditional and unconditional jumps and call instructions. The flow of a program wil be proceed sequentially from instruction to instruction, unless a control transfer instruction is executed. The looping action will be performed using a instruction DJNZ which decrements a couter and jumps to the top of the loop if the value counter is not zero. Jump conditionally instructions based on the value of the carry flag, the accumulator, or bits of the I/O port. Unconditional jumps can be long or short, depending upon the relative value of the target address.
What is Looping in the 8051 Assembly Language Programming:
Loop is defined as repeating a sequence of instructions a certain number of times. The loop is one of most widely used action that any microprocessor performs. In the 8051, "DJNZ reg, label" performed the loop actions. In "DJNZ reg,label" instruction, the register is decrement, if it is not zero and jumps to the target address referred to by the label. The register is loaded with the counter of the number of repetitions prior to the start of the loop. In "DJNZ reg, label" instruction, the register is decrement and the decision to jump are combined into a single instruction.
Example # 1:
Lets write a program to clear Accumulator [A], then Add 5 to the accumulator 20 times:
Answer:
;This program adds value 3 to the Accumulator 20 times |
MOV A,#0 ;Accumulator=0, Clear Accumulator |
MOV R2,#20 ;Load counter R2=20 |
AGAIN: ADD A,#05 ;Add 05 to Accumulator |
DJNZ R2,AGAIN ;Repeat Until R2=0 [20 times] |
MOV R5,A ;Save Accumulator in R5 |
The R2 register is used as a counter. The counter R2 is first set to 20. In each iteration, the instruction DJNZ decrements R2 and checks its value. If R2 is not zero, it jumps to the target address associated with label "AGAIN". This looping action continues until R2 becomes zero. After R2 becomes zero, it falls through the loop and executes the instruction immediately below it, in this case the "MOV R5,A" instruction. In the DJNZ instruction that the registers can be any of R0-R7. The counter can also be a RAM location.
What is the Maximum Number of times the Loop can be repeated in Example # 1?:
In the Example # 1 The R2 holds the count and R2 is an 8-bit register, it can hold a maximum of FFH [255 Decimal]. The loop can be repeated a maximum of 256 times.
Loop Inside a Loop [NESTED LOOP]:
The maximum count is 256. But if we want to repeat an action more times than 256, we use a loop inside a loop, which is called nested loop. In nested loop, we use two registers to hold the count.
Example # 2:
Lets write a program to load the accumulator with the value 66H, and complement the accumulator ACC 600 times:
Answer:
700 is larger than 255 [the maximum capacity of any register], we use two registers to hold the count. We are using R2, R3 for the count.
MOV A,$66H ;Accumulator A=66H |
MOV R3,#10 ;R3=10, the outer loop count |
NEXT: MOV R2,#60 ;R2=60, the inner loop count |
AGAIN: CPL A ;Complement A register |
DJNZ R2,AGAIN ;Repeat inner loop 60 times |
DJNZ R3,NEXT ;Repeat outer loop 10, so 10X60=600 times CPL A run |
R2 is used to keep the inner loop count. In the instruction "DJNZ R2,AGAIN", whenever R2 becomes zero, it falls through and "DJNZ R3,NEXT" is executed. This instruction forces the CPU to load R2 with the count 60 and the inner loop starts again. This process will continue until R3 becomes zero and the outer loop is finished.
8051 Conditional Jump Instructions:
Instruction | Action of the Instruction |
---|---|
JZ | Jump if Accumulator A = 0 |
JNZ | Jump if Accumulator A ≠ 0 |
DJNZ | Decrement and jump if Accumulator A ≠ 0 |
CJNE A,byte | Compare and Jump if Accumulator A ≠ byte |
CJNE reg,#data | Compare and Jump if Accumulator A ≠ #data |
JC | Jump if Carry Flag CY = 1 |
JNC | Jump if Carry Flag CY = 0 |
JB | Jump if bit is set i.e. bit = 1 |
JNB | Jump if bit is not set i.e. bit = 0 |
JBC | Jump if bit is set and clear that bit i.e bit = 1 and clear bi |
Example # 3:
MOV A,R0 ;A = R0 |
JZ OVER ;Jump if accumulator A = 0 |
MOV A,R1 ;A = R1 |
JZ OVER ;Jump if accumulator A = 0 |
......... |
OVER: |
Either R0 or R1 is zero, it jumps to the label OVER. The JZ instruction can be used only for register accumulator A. It can used only check to see whether the Accumulator is zero. It does not apply to any other register.
Example # 4:
Lets write a program in which if R4 register contains the value 0. Then put 55H in R4 register:
Answer:
MOV A,R4 ;Copy R4 to accumulator A |
JNZ NEXT ;Jump if accumulator is not zero |
MOV R4,#55H ;Put value 55H into register R4 |
NEXT: .......... |
JNC [Jump if No Carry i.e. Jumps if Carry Flag = 0]:
In JNC instruction, the carry flag bit in the flag [PSW] register is used to make the decision weather to jump. In executing "JNC label", the processor looks ar the carry flag to see it if is raised carry flag CY = 1, if it is not, the CPU starts to fetch and execute instructions from the address of the label. If carry flag CY=1, it will not jump but will execute the next instruction below JNC.
JC [Jump if Carry i.e. Jumps if Carry Flag = 1]:
In JC instruction, if carry flag CY=1, it jumps to the target address.
JB [Jump if bit is high]:
JNB [Jump if bit is low]:
These bit manipulation instructions will be discussed in the upcoming chapters in details.
Example # 5:
Lets find the sum of the values 78H,F4H and E1H. Put the sum in registers R0 [low byte] and R5 [high byte]:
Answer:
MOV A,#0 ;Clear accumulator A=0 |
MOV R5,A ;Clear R5 |
ADD A,#78H ;Accumulator A=0+78H=78H |
JNC HERE_1 ;If No carry, add next number |
INC R5 ;If carry flag CY=1, increment R5 |
HERE_1: ADD A,#0F4H ;A=78H+F4=6C and carry flag CY=1,as [78H+F4=16C] |
JNC HERE_2 ;Jump if Carry flag CY=0 |
INC R5 ;If carry flag CY=1,then increment R5, i.e. R5=1 |
HERE_2: ADD A,#0E1H ;A=6C+E1=4D and carry flag CY=1,as [6C+E1=14D] |
JNC OVER ;Jump if carry flag CY=0 |
INC R5 ;If carry flag CY=1, increment R5 |
OVER: MOV R0,A ;Now R0=4D, and R5=02 |
END |
ALL Conditional Jumps are Short Jumps:
All conditional jumps are short jumps, as in that the address of the target must be within -128 to -127 bytes of the contents of the program counter [PC].
Unconditional Jump Instructions:
The unconditional jump is a jump in which control is transferred unconditionally to the target location. There are 2 unconditional jumps in the 8051: LJMP [Long Jump] and SJMP [Short Jump].
- Long Jump [LJMP]:
LJMP [Long Jump] is an unconditional long jump. LJMP is a 3-byte instruction in which the first byte is the opcode, and the second and third bytes represent the 16-bit address of the target location. The 2-byte target address allows a jump to any memory location from 0000 to FFFFH. The program counter [PC] is a 16-bit in the 8051,giving a ROM address space of 64K bytes. Not all family members of 8051 have this much on-chip program ROM. The original 8051 had only 4K-bytes of on-chip ROM for program space. For this reason, there is also a short jump SJMP instruction which is a 2-byte instruction as opposed to the 3-byte instruction which is long jump LJMP. Using short jump SJMP save some bytes of memory in many applications where memory space in short supply.
- Short Jump [SJMP]:
Short Jump [SJMP] is a two byte instruction. The first byte is the opcode and the second byte is the relative address of the target location. The relative address range of 00 - FFH is divided into forward and backward jumps. Memory relative to the address of the current PC [Program counter} is within the -128 to +128 bytes. The target address in within 127 bytes from the current PC [Program counter], if the jump is forward. The target address is within -128 bytes from the current PC [Program counter], if the jump is backward.
Short Jump Address Calculations:
All conditional jumps such as JNC, JZ and DJNZ are short jumps. They are all 2-byte instructions. In these instructions, the first byte is the opcode and the second byte is the relative address. The target address is relative to the value of the program counter [PC]. To calculate the target address, the second byte is added to the PC [program counter] of the instruction immediately below the jump.
Example # 6:
Lets verify the jump forward address calculation.
LINE | PROGRAM COUNTER [PC] | OPCODE | MNEMONIC OPERAND |
01 | 0000 | ORG 0000 | |
02 | 0000 | 7800 | MOV R0,#01 |
03 | 0002 | 7455 | MOV A,#66H |
04 | 0004 | 6003 | JZ NEXT |
05 | 0006 | 08 | INC R1 |
06 | 0007 | 04 | AGAIN: INC A |
07 | 0008 | 04 | INC A |
08 | 0009 | 2477 | NEXT: ADD A,#77H |
09 | 000B | 5005 | JNC OVER |
10 | 000D | E4 | CLR A |
11 | 000E | F8 | MOV R3,A |
12 | 000F | F9 | MOV R2,A |
13 | 0010 | FA | MOV R1,A |
14 | 0011 | FB | MOV R0,A |
15 | 0012 | 2B | OVER ADD A,R3 |
16 | 0013 | 50F2 | JNC AGAIN |
17 | 0015 | 80FE | SJMP HERE |
18 | 0017 | END |
Answer:
The target address for a forward jump is calculated by adding the program counter [PC] of the following instruction to the second byte of the short jump instruction, which is called the relative address. JZ and JNC instructions both jump forward. In line 04, the instruction "JZ NEXT" has opcode of '60' and operand of '03' at the program counter [PC] address of '0004' and '0005'. The 03 is the relative address, relative to the address of the next instruction "INC R0" at program counter address of '0006'. By adding 0006 to 03, the target address os the label NEXT, 0009 is generated, where the jump will take place at NEXT: ADD A,#77H. In the same way, at line 09, the "JNC OVER instruction has opcode and operand of '50' and '05', where '50' is the opcode and '05' is the relative address. So 05 is added to 000D, the address if instruction "CLR A", resulting in 0012, the address of the label OVER of mnemonic operand 'OVER ADD A,R3'.
Backward Jumps Verification in Example # 6:
"JNC AGAIN" has opcode 50 and relative address F2H. This relative address F2H is added to program counter address 0015 or 15H, the address of the instruction below the jump, resulting 15H + F2H = 107, after dropping the carry, 15H + F2H = 07 [the carry is dropped]. 0007 is the PC address of the 'AGAIN: INC A' mnemonic operand. In the same way, 'SJMP HERE' which has 80 and FE for the opcode and relative address. The program counter of the following instruction 0017H is added to FEH, the relative address, to get 0015H, the address of the HERE label [17H+FEH = 15H]. FEH is -2 and 17H+(-2)=15H.
Backward Jump Target Address Calculations:
The displacement value is positive number in the case of forward jump, i.e. between 0 to 127, 00 to 7F in hex.
The displacement value is negative in the case of backward jump, i.e. 0 to -128.
The short jump, SJMP is forward or backward, the address of the target address can never be more than -128 to +127 bytes from the address associated with the instruction below the SJMP. The assembler will generate an error of out of range if any attempt is made to violate this rule.