📜  用于二分查找的 8085 程序

📅  最后修改于: 2022-05-13 01:57:05.065000             🧑  作者: Mango

用于二分查找的 8085 程序

先决条件 - 二分搜索
问题——在 8085 微处理器中编写一个汇编语言程序,在 10 个数字的列表中找到一个给定的数字。如果找到将 1 存储在输出中,否则将 2 存储在输出中。此外,存储迭代次数和元素的索引(如果找到)。

示例:让列表如下:

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 

假设 -
假设要与之比较的数据存储在3000H中,数字列表从3010H到3019H,结果存储如下:3003H中的迭代次数,3001H中的成功/失败(1/2)和3002H中的索引

算法 -

  1. 将 0 移到 Accumulator 并存储在 3003H 中,表示到目前为止的迭代次数。
  2. 将 0 和 9 分别移动到 L 和 H 寄存器。
  3. 从 3000H 加载累加器中要搜索的数据,并将其移至 B 寄存器。
  4. 从 3003H 中检索迭代次数,将其加一并存储回 3003H。
  5. 将 H 寄存器的值移动到累加器并与 L 寄存器进行比较。
  6. 如果产生进位,则二进制搜索结束,因此跳转到第 20 步。
  7. 将 L 寄存器的值加到累加器并右移。
  8. 将累加器的值存储在寄存器 C 中并强制复位进位标志(如果设置)。
  9. 在 DE 寄存器对中加载数组的起始地址。
  10. 将累加器的值加到寄存器 E 并将结果存储在 E 中。
  11. 将 0 移至累加器并使用 ADC 命令将由于先前加法产生的任何可能的进位相加,并将其存储回寄存器 D。
  12. 加载 DE 对指向的值并与寄存器 B 比较。如果产生进位,则跳转到第 15 步,如果设置了零标志,则跳转到第 17 步。
  13. 将寄存器 C 的值移动到累加器并递减累加器。
  14. 将累加器的值移动到 H 并跳转回第 4 步。
  15. 将寄存器 C 的值移动到累加器并递增累加器。
  16. 将累加器的值移动到 L 并跳转回第 4 步。
  17. 将 1 移至 3001H 中的 Accumulator ad store 表示成功。
  18. 将寄存器 C 的值移动到累加器并存储在 3002H 中以保存索引。
  19. 跳转到声明 21。
  20. 将 2 移到 Accumulator 并存入 3001H 表示失败。
  21. 结束程序。

程序 -

AddressLabelInstructionComment
2000H LDA 3000HLoad value to search for
2003H MOV B, ASave it in register B
2004H MVI A, 0 
2006H STA 3003HStore iteration number
2009H M0V L, A 
200AH MVI A, 9 
200CH MOV H, AStoring high and low indices in H-L pair done
200DHstart_loop:LDA 3003HLoad iteration number
2010H INR AIncrement iteration number
2011H STA 3003HStore back in 3003H
2014H MOV A, HStore high index in Accumulator
2015H CMP LCompare with lower index
2016H JC loop_endIf carry generated, this means high is less than low so binary search over
2019H ADD LAdd high to low
202AH RARRight rotate to divide by two and generate mid
202BH MOV C, ASave mid in register C
202CH JNC resetIf carry flag unset, go directly to reset.
202FH CMCForce unset carry flag
2030HresetNOP 
2031H LXI D, 3010HLoad start address in D-E pair
2034H ADD EAdd mid to E to get the offset
2035H MOV E, AGet the changed address back in E so it becomes a pointer to arr[mid]
2036H MVI A, 0Handle possible overflow
2038H ADC D 
2039H MOV D, AMemory index handled
203AH LDAX DLoad the array element in accumulator
203BH CMP BCompare with value to search
203CH JC else_blockImplies value is greater than value at mid, so we need low=mid+1
203FH JZ printIf zero flag set, match found. Jump to print block
2042H MOV A, CNeither executed so value
2043H DCR Amid=mid-1
2044H MOV H, Ah=mid
2045H JMP start_loopJump back
2046Helse_blockMOV A, CWe need low=mid+1
2047H INR Amid=mid+1
2048H MOV A, Ll=mid
2049H JMP start_loop 
204CHprintMVI A, 1Move 1 to Accumulator
204EH STA 3001HStore it in 3001H to indicate success
2051H MOV A, CMove index, that is mid, back to Accumulator
2052H STA 3002HStore it in 3002H
2055H JMP true_endJump to end of the code
2058Hloop_endMVI A, 2 
205AH STA 3001HStore 2 in 3001H to indicate failure
205DHtrue_endHLTTerminate

解释 -

  1. 我们在步骤 2 中将较高和较低索引的值(在本例中为 9 和 0)分别移动到 H 和 L 寄存器
  2. 在第 5 步中比较较高和较低的指数。在得到一个进位(表示低>高)时,我们跳到循环结束,否则转到第 6 步。
  3. 在第 7 步和第 8 步中,我们将 H 和 L 寄存器的值相加并右移,相当于 (high+low)/2 以便在 C 语言中找到索引
  4. 在第 10 步中,我们将 mid 的值添加到数组的起始地址,使其充当偏移量,类似于 C 中 *(arr+x) 和 arr[x] 的相同方式。
  5. 步骤 11 确保不会发生溢出。
  6. 在第 12 步中,我们将中间索引处的值与要搜索的值进行比较。如果相等,我们跳出循环并适当地设置值。
  7. 如果它们不相等,则第 12 步适当地分支,让我们将 mid 递增/递减 1 并将该值移动到 L/H 寄存器,必要时(就像在 C 中完成的 high=mid-1 或 low=mid+1 一样)并返回循环开始,即第 2 步。

注意 –如果要搜索的元素小于数组中的最小元素,此方法将失败。为了处理这个问题,在循环的开头添加一个额外的零,并在步骤 2 中分别将值 10 和 1 移动到 HL 对。