一、?實驗要求
- 熟練掌握循環程序設計的基本方法
- 熟練掌握單片機外部存儲空間的訪問方法
二、?實驗設計
?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。
??????????????
三、?實現效果
四、總結
- 在一開始設計程序的時候,我以為給出的代碼已經儲存了SRC與DEST的地址位置,不需要在額外用寄存器再儲存。事實證明,這是個很天真的想法,于是我使用R1與DPTR進行儲存了。
- 在寫入數據的時候,原先我想直接將R1,也就是記錄num的寄存器直接與$比較,后面發現程序不允許。于是增加了中間商DPTR進行操作。
- 通過這次實驗更加加深了對循環程序設計的認識,也懂了一些單片機外部儲存空間的訪問方法。
附錄:
ORG 0000HLJMP MAINORG 2000H
MAIN: SRC DATA 30HDEST XDATA 2000HNUM DATA 20HACALL Procedure1ACALL Procedure2SJMP $Procedure1: ; 將數據從 SRC 復制到 DESTMOV R0, #0 ; R0 用于計數MOV R1, #SRC ; R1 存儲 SRC 的地址
MOV DPTR,#DEST ; 保存DEST起始地址Procedure1_LOOP:CJNE R0, #NUM, Write ; 檢查R0是否等于NUM,如果不等于,則跳轉到 Write SJMP ENGING1Write:MOV A, @R1 ; 從 SRC 讀取數據到 A 寄存器MOVX @DPTR, A ; 將 A 寄存器的值寫入到 DPTR 所指向的位置INC R0 ; 增加計數器 R0INC R1 ; 增加指向下一個字節的地址CJNE A, '$', Write ; 查A的值是否等于'$',如果不等于,則跳轉回 WriteSJMP ENGING1ENGING1:RET ; 從子程序返回Procedure2: ; 從 SRC 中,向起始地址為 DEST 的片外存儲中,逆序拷貝之前存儲的 NUM 個單字節數MOV R0, #0 ; R0 用于計數MOV R1, #SRC ; R1 存儲 SRC 的地址Procedure2_LOOP: CJNE R0, #NUM, copy ; 從SRC的末尾開始向 DEST 的末尾復制數據SJMP ENGING2Copy:MOV A, @R1 ; 從 SRC 讀取數據到 A 寄存器MOVX @DPTR, A ; 將 A 寄存器的值寫入到 DPTR 所指向的位置INC R0 ; 增加計數器 R0DEC R1 ; 減小指向上一個字節的地址CJNE A, '$', Copy ; 檢查A的值是否等于'$',如果不等于,則跳轉回CopySJMP ENGING2ENGING2:RETEND