汇编:循环程序设计

发布于:2025-05-18 ⋅ 阅读:(21) ⋅ 点赞:(0)

一、 实验要求

  1. 熟练掌握循环程序设计的基本方法
  2. 熟练掌握单片机外部存储空间的访问方法

二、 实验设计

 1.整体思路

先初始化一些寄存器和数据存储位置,然后调用两个子程序Procedure1和Procedure2,分别从SRC复制数据到DEST,一个从开头到末尾,另一个从末尾到开头。每个子程序在复制数据时使用循环,直到达到指定的复制次数(由NUM控制)。程序最后通过END标志结束。

2.流程图

3.主要模块设计思路及分析

(1)Procedure1子程序

  • Procedure1 负责向起始地址为SRC的片内存储中,顺序写入NUM个单字节数(数值不限),并以$字符(ASCII码)结尾。。
  • R0 用于计数,R1 存储 SRC 的地址。
  • 使用循环,CJNE 指令检查 R0 是否等于 NUM,如果等于,就跳到 ENGING1,否则继续执行。
  • 在循环中,从 SRC 读取数据到寄存器 A,然后使用 MOVX 指令将 A 的值写入到 DPTR 所指向的位置。然后增加计数器 R0 和地址 R1。
  • 再次使用 CJNE 指令检查 A 的值是否等于 '$',如果不等于,就回到 Write,否则跳到 ENGING1。

(2)Procedure2子程序

  • Procedure2 负责2.从SRC中,向起始地址为DEST的片外存储中,逆序拷贝之前存储的NUM个单字节数,并以$字符结尾。R0 用于计数,R1 存储 SRC 的地址。
  • 同样使用循环,CJNE 指令检查 R0 是否等于 NUM,如果等于,就跳到 ENGING2,否则继续执行。
  • 在循环中,从 SRC 读取数据到寄存器 A,然后使用 MOVX 指令将 A 的值写入到 DPTR 所指向的位置。然后增加计数器 R0,但是减小地址 R1 以实现逆序复制。
  • 再次使用 CJNE 指令检查 A 的值是否等于 '$',如果不等于,就回到 Copy,否则跳到 ENGING2。

              

三、 实现效果

四、总结

  1. 在一开始设计程序的时候,我以为给出的代码已经储存了SRC与DEST的地址位置,不需要在额外用寄存器再储存。事实证明,这是个很天真的想法,于是我使用R1与DPTR进行储存了。
  2. 在写入数据的时候,原先我想直接将R1,也就是记录num的寄存器直接与$比较,后面发现程序不允许。于是增加了中间商DPTR进行操作。
  3. 通过这次实验更加加深了对循环程序设计的认识,也懂了一些单片机外部储存空间的访问方法。

附录:

ORG 	0000H
	LJMP 	MAIN

	ORG 	2000H
MAIN:	
    SRC		DATA 	30H
    DEST   	XDATA 	2000H
    NUM	    DATA	20H
    
	ACALL Procedure1
    ACALL Procedure2

    SJMP $

Procedure1:			 ; 将数据从 SRC 复制到 DEST
    MOV R0, #0       ; R0 用于计数
    MOV R1, #SRC     ; R1 存储 SRC 的地址
MOV DPTR,#DEST   ; 保存DEST起始地址

Procedure1_LOOP:
    CJNE R0, #NUM, Write   ; 检查R0是否等于NUM,如果不等于,则跳转到 Write 
    SJMP ENGING1

Write:
    MOV A, @R1       ; 从 SRC 读取数据到 A 寄存器
    MOVX @DPTR, A    ; 将 A 寄存器的值写入到 DPTR 所指向的位置
    INC R0           ; 增加计数器 R0
    INC R1           ; 增加指向下一个字节的地址

    CJNE A, '$', Write	   ; 查A的值是否等于'$',如果不等于,则跳转回 Write
    SJMP ENGING1

ENGING1:
    RET				 ; 从子程序返回

Procedure2:			 ; 从 SRC 中,向起始地址为 DEST 的片外存储中,逆序拷贝之前存储的 NUM 个单字节数
    MOV R0, #0       ; R0 用于计数
    MOV R1, #SRC     ; R1 存储 SRC 的地址

Procedure2_LOOP:	 
    CJNE R0, #NUM, copy	   ; 从SRC的末尾开始向 DEST 的末尾复制数据
    SJMP ENGING2

Copy:
    MOV A, @R1       ; 从 SRC 读取数据到 A 寄存器
    MOVX @DPTR, A    ; 将 A 寄存器的值写入到 DPTR 所指向的位置
    INC R0           ; 增加计数器 R0
    DEC R1           ; 减小指向上一个字节的地址

    CJNE A, '$', Copy	   ; 检查A的值是否等于'$',如果不等于,则跳转回Copy
    SJMP ENGING2

ENGING2:
    RET

    END