AT89S52单片机汇编语言实现插入排序求助(Keil环境)
AT89S52汇编实现插入排序(针对05H、01H、04H、02H、08H)
我正在使用Keil环境为AT89S52微处理器编写汇编程序,在YouTube上找到的基础教程多为C语言内容,对我帮助有限,因此在此求助。我需要对数值05H、01H、04H、02H、08H实现插入排序,但始终无法完成所需循环,现附上当前代码:
ORG 0000H AJMP MAIN ORG 0040H MAIN: MOV DPTR, #70H MOV A, #05H MOVX @DPTR, A INC DPTR MOV A, #01H MOVX @DPTR, A INC DPTR MOV A, #04H MOVX @DPTR, A INC DPTR MOV A, #02H MOVX @DPTR, A INC DPTR MOV A, #08H MOVX @DPTR, A MOV R0, #1H CJNE R0, #5H, CICLO CICLO: //loop MOV R1, R0 END
问题分析
你的代码仅完成了数据初始化,循环逻辑完全缺失:外层循环没有实现递增和终止判断,也没有插入排序核心的元素比较、后移、插入逻辑。下面是完整的插入排序实现,针对AT89S52的外部RAM操作优化。
完整实现代码
ORG 0000H AJMP MAIN ORG 0040H MAIN: ; 步骤1:将待排序数据写入外部RAM 70H~74H MOV DPTR, #70H MOV A, #05H MOVX @DPTR, A INC DPTR MOV A, #01H MOVX @DPTR, A INC DPTR MOV A, #04H MOVX @DPTR, A INC DPTR MOV A, #02H MOVX @DPTR, A INC DPTR MOV A, #08H MOVX @DPTR, A ; 步骤2:插入排序核心逻辑(升序) MOV R0, #1H ; 外层循环:从第2个元素(索引1)开始,共处理4次 OUT_LOOP: ; 保存当前待插入的元素 MOV DPTR, #70H MOV A, R0 ADD A, DPL ; 计算当前元素的外部RAM地址:70H + R0 MOV DPL, A MOVX A, @DPTR MOV R2, A ; R2暂存待插入值 MOV R1, R0 ; 内层循环:从当前位置向前遍历已排序序列 IN_LOOP: DEC R1 CJNE R1, #0FFH, COMPARE ; 未遍历到序列开头,继续比较 ; 遍历到开头,直接插入当前位置 MOV DPTR, #70H MOV A, R0 ADD A, DPL MOV DPL, A MOV A, R2 MOVX @DPTR, A SJMP NEXT_OUT COMPARE: ; 获取前一个元素的值 MOV DPTR, #70H MOV A, R1 ADD A, DPL MOV DPL, A MOVX A, @DPTR CJNE A, R2, CHECK_GREATER CHECK_GREATER: JC INSERT ; 前一个元素 < 待插入元素,找到插入位置 ; 前一个元素 >= 待插入元素,将其向后移动一位 INC DPL ; 地址+1(后移位置) MOVX @DPTR, A SJMP IN_LOOP ; 继续向前比较 INSERT: ; 将待插入元素写入正确位置 MOV DPTR, #70H MOV A, R1 ADD A, #1 ADD A, DPL MOV DPL, A MOV A, R2 MOVX @DPTR, A NEXT_OUT: INC R0 CJNE R0, #5H, OUT_LOOP ; 外层循环直到处理完所有5个元素 ; 排序完成,程序停在此处 LOOP_END: SJMP LOOP_END END
关键逻辑说明
- 外层循环:用
R0从1到4(对应第2到第5个元素),逐个处理需要插入的元素。 - 内层循环:从当前元素位置向前遍历已排序序列,完成两个操作:
- 若前一个元素大于待插入元素,将其向后移动一位;
- 找到小于待插入元素的位置(或序列开头),将待插入元素插入。
- RAM操作优化:通过
ADD A, DPL计算外部RAM地址,避免频繁使用INC DPTR,提升效率。 - 排序方向调整:如果需要降序排序,只需将
CHECK_GREATER段的JC INSERT改为JNC INSERT即可。
内容的提问来源于stack exchange,提问作者Ramenyum
相关产品推荐
相关产品推荐

