7.0 Program Control: Jumps, Loops, and Calls
Programs rarely execute in a simple, linear sequence from start to finish. Control transfer instructions are essential for altering this flow, allowing for decision-making, repetition, and structured code. This section covers the fundamental 8051 instructions for creating loops, making conditional jumps, and organizing code into reusable subroutines.
7.1 Looping Constructs
A loop is a sequence of instructions that is repeated a certain number of times. The primary instruction for creating loops in the 8051 is DJNZ.
- DJNZ reg, label (Decrement and Jump if Not Zero): This powerful instruction combines two actions. First, it decrements the specified register (R0-R7). Second, if the register’s value is not yet zero, it jumps to the target label. This instruction is limited to a maximum of 256 iterations since the registers are 8-bit.
- Nested Loops: To achieve more than 256 iterations, you can use a loop inside another loop. An outer loop can reload the counter for an inner loop, allowing for a much larger number of repetitions.
7.2 Conditional Jumps
Conditional jumps alter the program flow based on the status of CPU flags or the value in a register. These instructions are the foundation of decision-making in assembly language.
| Mnemonic | Description |
| JZ | Jump if Accumulator is Zero. |
| JNZ | Jump if Accumulator is Not Zero. |
| JC | Jump if Carry flag is set (CY = 1). |
| JNC | Jump if No Carry (CY = 0). |
| JB | Jump if Bit is set to 1. |
| JNB | Jump if Bit is not set (is 0). |
| JBC | Jump if Bit is 1, then clear the bit. |
| CJNE A, data | Jump if Accumulator is not equal to the specified data. |
| CJNE reg, #data | Jump if Register is not equal to the specified data. |
All conditional jumps are short jumps, meaning the target address must be within a range of -128 to +127 bytes from the current location of the Program Counter.
7.3 Unconditional Jumps
Unconditional jumps always transfer program control to a new location, regardless of any CPU status.
- LJMP (Long Jump): This is a 3-byte instruction that can jump to any memory location within the entire 64K address space of the 8051.
- SJMP (Short Jump): This is a 2-byte instruction that uses a relative address. It is more memory-efficient but can only jump to a target within a -128 to +127 byte range from the current instruction.
7.4 Subroutines: CALL and RET Instructions
Subroutines are blocks of reusable code that can be “called” from multiple places in a main program. They are essential for creating structured, modular, and memory-efficient programs.
The 8051 provides two instructions to call a subroutine:
- LCALL (Long Call): A 3-byte instruction that can call a subroutine located anywhere in the 64K address space.
- ACALL (Absolute Call): A more efficient 2-byte instruction, but it can only call subroutines within a 2K-byte range.
When a CALL instruction is executed, the 8051 automatically pushes the address of the next instruction (from the Program Counter) onto the stack. This saves the “return address.” The last instruction in every subroutine must be RET (Return). The RET instruction pops the saved address from the stack back into the Program Counter, allowing the main program to resume exactly where it left off.
So far, we have focused on the internal logic of an 8051 program. The next section shifts our attention to how the 8051 interacts with the external world through its I/O ports.