Prerequisite – Binary Search

**Problem –** Write an assembly language program in the 8085 microprocessor to find a given number in the list of 10 numbers. If found store 1 in output, else store 2 in output. Also, store the number of iterations and the index of the element, if found.

**Example:** Let the list be as follows:

Test-1:Input:21H (at 3000H)Output:1 (success) in 3001H, 2 (index) in 3002H, and 3 (iteration number) in 3003H.Test-2:Input:22H (at 3000H)Output:2 (failure) in 3001H, X (don't care) in 3002H, and 4 (iteration before failure) in 3003H

**Assumption –**

Assume data to compare it with is stored in 3000H, list of numbers is from 3010H to 3019H and results are stored as follows: number of iterations in 3003H, success/failure (1/2) in 3001H and index in 3002H

**Algorithm –**

- Move 0 to Accumulator and store it in 3003H, to indicate number of iterations so far.
- Move 0 and 9 to L and H registers, respectively.
- Load the data to search for in Accumulator from 3000H and shift it to B register.
- Retrieve the number of iterations from 3003H, increase it by one and store back in 3003H.
- Move value of H register to Accumulator and compare with L register.
- If carry is generated, binary search is over so JUMP to step 20.
- Add value of L register to Accumulator and right rotate it.
- Store value of Accumulator in register C and force reset carry flag, if set.
- Load the start address of the array in D-E register pair.
- Add the value of accumulator to Register E and store the result in E.
- Move 0 to Accumulator and use the ADC command to add any possible carry generated due to previous addition and store it back in Register D.
- Load the value pointed to by D-E pair and compare with Register B. If carry is generated, JUMP to step 15 and if Zero flag is set, JUMP to step 17.
- Move value of Register C to Accumulator and decrement Accumulator.
- Move value of Accumulator to H and JUMP back to step 4.
- Move value of Register C to Accumulator and increment Accumulator.
- Move value of Accumulator to L and JUMP back to step 4.
- Move 1 to Accumulator ad store in 3001H to indicate success.
- Move value of Register C to Accumulator and store it in 3002H to save the index.
- JUMP to statement 21.
- Move 2 to Accumulator and store it in 3001H to indicate failure.
- End the program.

**Program –**

;

Address | Label | Instruction | Comment |
---|---|---|---|

2000H | LDA 3000H | Load value to search for | |

2003H | MOV B, A | Save it in register B | |

2004H | MVI A, 0 | ||

2006H | STA 3003H | Store iteration number | |

2009H | M0V L, A | ||

200AH | MVI A, 9 | ||

200CH | MOV H, A | Storing high and low indices in H-L pair done | |

200DH | start_loop: | LDA 3003H | Load iteration number |

2010H | INR A | Increment iteration number | |

2011H | STA 3003H | Store back in 3003H | |

2014H | MOV A, H | Store high index in Accumulator | |

2015H | CMP L | Compare with lower index | |

2016H | JC loop_end | If carry generated, this means high is less than low so binary search over | |

2019H | ADD L | Add high to low | |

202AH | RAR | Right rotate to divide by two and generate mid | |

202BH | MOV C, A | Save mid in register C | |

202CH | JNC reset | If carry flag unset, go directly to reset. | |

202FH | CMC | Force unset carry flag | |

2030H | reset | NOP | |

2031H | LXI D, 3010H | Load start address in D-E pair | |

2034H | ADD E | Add mid to E to get the offset | |

2035H | MOV E, A | Get the changed address back in E so it becomes a pointer to arr[mid] | |

2036H | MVI A, 0 | Handle possible overflow | |

2038H | ADC D | ||

2039H | MOV D, A | Memory index handled | |

203AH | LDAX D | Load the array element in accumulator | |

203BH | CMP B | Compare with value to search | |

203CH | JC else_block | Implies value is greater than value at mid, so we need low=mid+1 | |

203FH | JZ print | If zero flag set, match found. Jump to print block | |

2042H | MOV A, C | Neither executed so value<mid and we need high=mid-1 | |

2043H | DCR A | mid=mid-1 | |

2044H | MOV H, A | h=mid | |

2045H | JMP start_loop | Jump back | |

2046H | else_block | MOV A, C | We need low=mid+1 |

2047H | INR A | mid=mid+1 | |

2048H | MOV A, L | l=mid | |

2049H | JMP start_loop | ||

204CH | MVI A, 1 | Move 1 to Accumulator | |

204EH | STA 3001H | Store it in 3001H to indiate success | |

2051H | MOV A, C | Move index, that is mid, back to Accumulator | |

2052H | STA 3002H | Store it in 3002H | |

2055H | JMP true_end | Jump to end of the code | |

2058H | loop_end | MVI A, 2 | |

205AH | STA 3001H | Store 2 in 3001H to indicate failure | |

205DH | true_end | HLT | Terminate |

**Explanation –**

- We move value of higher and lower index (9 and 0 in this case) to H and L registers respectively in step 2
- Higher and lower indices are compared in step 5. On getting a carry, which indicates low>high, we jump to end of loop else go to step 6.
- In steps 7 and 8 we add value of H and L registers and right rotate it, which is equivalent to (high+low)/2 in order to find the index in say C language
- In step 10, we add the value of mid to start address of array so that it acts as an offset, similar to how *(arr+x) and arr[x] is identical in C.
- Step 11 ensures no overflow occurs.
- In step 12, we compare the value at mid index with the value to be searched. If it’s equal, we jump out of the loop and set the values appropriately.
- If they are not equal, step 12 branches appropriately to let us increment/decrement mid by 1 and move that value to L/H register, as necessary (just like high=mid-1 or low=mid+1 is done in C) and go back to start of loop, that is step 2.

**Note –** This approach will fail if the element to be searched is smaller than the smallest element in the array. In order to handle that, add an extra zero to the start of the loop and move values 10 and 1 to H-L pair in step 2, respectively.