# Embedded Systems - Instructions

The flow of program proceeds in a sequential manner, from one instruction to the next instruction, unless a control transfer instruction is executed. The various types of control transfer instruction in assembly language include conditional or unconditional jumps and call instructions.

## Loop and Jump Instructions

### Looping in the 8051

Repeating a sequence of instructions a certain number of times is called a loop. An instruction DJNZ reg, label is used to perform a Loop operation. In this instruction, a register is decremented by 1; if it is not zero, then 8051 jumps to the target address referred to by the label.

The register is loaded with the counter for the number of repetitions prior to the start of the loop. In this instruction, both the registers decrement and the decision to jump are combined into a single instruction. The registers can be any of R0–R7. The counter can also be a RAM location.

### Example

Multiply 25 by 10 using the technique of repeated addition.

Solution − Multiplication can be achieved by adding the multiplicand repeatedly, as many times as the multiplier. For example,

25 * 10 = 250(FAH)

25 + 25 + 25 + 25 + 25 + 25 + 25 + 25 + 25 + 25 = 250

```   MOV A,#0             ;A = 0,clean ACC
MOV R2,#10           ; the multiplier is replaced in R2

AGAIN:DJNZ R2,
AGAIN:repeat  until R2 = 0 (10 times)

MOV R5 , A           ;save A in R5 ;R5 (FAH)
```

Drawback in 8051 − Looping action with the instruction DJNZ Reg label is limited to 256 iterations only. If a conditional jump is not taken, then the instruction following the jump is executed.

### Looping inside a Loop

When we use a loop inside another loop, it is called a nested loop. Two registers are used to hold the count when the maximum count is limited to 256. So we use this method to repeat the action more times than 256.

Example

Write a program to −

• Load the accumulator with the value 55H.
• Complement the ACC 700 times.

Solution − Since 700 is greater than 255 (the maximum capacity of any register), two registers are used to hold the count. The following code shows how to use two registers, R2 and R3, for the count.

```   MOV A,#55H            ;A = 55H

NEXT: MOV R3,#10         ;R3 the outer loop counter
AGAIN:MOV R2,#70         ;R2 the inner loop counter

CPL A                 ;complement
```

## Other Conditional Jumps

The following table lists the conditional jumps used in 8051 −

Instruction Action
JZ Jump if A = 0
JNZ Jump if A ≠ 0
DJNZ Decrement and Jump if register ≠ 0
CJNE A, data Jump if A ≠ data
CJNE reg, #data Jump if byte ≠ data
JC Jump if CY = 1
JNC Jump if CY ≠ 1
JB Jump if bit = 1
JNB Jump if bit = 0
JBC Jump if bit = 1 and clear bit
• JZ (jump if A = 0) − In this instruction, the content of the accumulator is checked. If it is zero, then the 8051 jumps to the target address. JZ instruction can be used only for the accumulator, it does not apply to any other register.

• JNZ (jump if A is not equal to 0) − In this instruction, the content of the accumulator is checked to be non-zero. If it is not zero, then the 8051 jumps to the target address.

• JNC (Jump if no carry, jumps if CY = 0) − The Carry flag bit in the flag (or PSW) register is used to make the decision whether to jump or not "JNC label". The CPU looks at the carry flag to see if it is raised (CY = 1). If it is not raised, then the CPU starts to fetch and execute instructions from the address of the label. If CY = 1, it will not jump but will execute the next instruction below JNC.

• JC (Jump if carry, jumps if CY = 1) − If CY = 1, it jumps to the target address.

• JB (jump if bit is high)

• JNB (jump if bit is low)

Note − It must be noted that all conditional jumps are short jumps, i.e., the address of the target must be within –128 to +127 bytes of the contents of the program counter.

## Unconditional Jump Instructions

There are two unconditional jumps in 8051 −

• LJMP (long jump) − LJMP is 3-byte instruction in which the first byte represents opcode, and the second and third bytes represent the 16-bit address of the target location. The 2-byte target address is to allow a jump to any memory location from 0000 to FFFFH.

• SJMP (short jump) − It is a 2-byte instruction where the first byte is the opcode and the second byte is the relative address of the target location. The relative address ranges from 00H to FFH which is divided into forward and backward jumps; that is, within –128 to +127 bytes of memory relative to the address of the current PC (program counter). In case of forward jump, the target address can be within a space of 127 bytes from the current PC. In case of backward jump, the target address can be within –128 bytes from the current PC.

## Calculating the Short Jump Address

All conditional jumps (JNC, JZ, and DJNZ) are short jumps because they are 2-byte instructions. In these instructions, the first byte represents opcode and the second byte represents the relative address. The target address is always relative to the value of the program counter. To calculate the target address, the second byte is added to the PC of the instruction immediately below the jump. Take a look at the program given below −

```Line   PC    Op-code   Mnemonic   Operand
1      0000               ORG       0000
2      0000  7800         MOV       R0,#003
3      0002  7455         MOV       A,#55H0
4      0004  6003         JZ        NEXT
5      0006  08           INC       R0
6      0007  04   AGAIN:  INC       A
7      0008  04           INC       A
8      0009  2477 NEXT:   ADD       A, #77h
9      000B  5005         JNC       OVER
10     000D  E4           CLR       A
11     000E  F8           MOV       R0, A
12     000F  F9           MOV       R1, A
13     0010  FA          MOV       R2, A
14     0011  FB           MOV       R3, A
15     0012  2B   OVER:   ADD       A, R3
16     0013  50F2         JNC       AGAIN
17     0015  80FE HERE:   SJMP      HERE
18     0017             END
```

### Backward Jump Target Address Calculation

In case of a forward jump, the displacement value is a positive number between 0 to 127 (00 to 7F in hex). However, for a backward jump, the displacement is a negative value of 0 to –128.

## CALL Instructions

CALL is used to call a subroutine or method. Subroutines are used to perform operations or tasks that need to be performed frequently. This makes a program more structured and saves memory space. There are two instructions − LCALL and ACALL.

### LCALL (Long Call)

LCALL is a 3-byte instruction where the first byte represents the opcode and the second and third bytes are used to provide the address of the target subroutine. LCALL can be used to call subroutines which are available within the 64K-byte address space of the 8051.

To make a successful return to the point after execution of the called subroutine, the CPU saves the address of the instruction immediately below the LCALL on the stack. Thus, when a subroutine is called, the control is transferred to that subroutine, and the processor saves the PC (program counter) on the stack and begins to fetch instructions from the new location. The instruction RET (return) transfers the control back to the caller after finishing execution of the subroutine. Every subroutine uses RET as the last instruction.

### ACALL (Absolute Call)

ACALL is a 2-byte instruction, in contrast to LCALL which is 3 bytes. The target address of the subroutine must be within 2K bytes because only 11 bits of the 2 bytes are used for address. The difference between the ACALL and LCALL is that the target address for LCALL can be anywhere within the 64K-bytes address space of the 8051, while the target address of CALL is within a 2K-byte range.