嵌入式ARM設計程式設計(一) 簡單資料搬移

語言: CN / TW / HK

文章和程式碼已歸檔至【Github倉庫:hardware-tutorial】,需要的朋友們自取。或者關注公眾號【AIShareLab】,回覆 嵌入式 也可獲取。

一、實驗目的

熟悉實驗開發環境,掌握簡單ARM彙編指令的使用方法。

二、實驗環境

硬體:PC機

軟體:ADS1.2 整合開發環境

三、實驗內容

熟悉開發環境並使用LDR/STR,MOV等指令訪問暫存器或儲存單元;

使用ADD/SUB/LSL/LSR/AND/ORR等指令,完成基本數學/邏輯運算。

四、實驗要求

(1)按照2.3節介紹的方法, 在ADS下建立一個工程asmlab1,定義兩個變數x,y和堆疊地址0x1000,將變數x的內容存到堆疊頂,然後計算x+y,並將和存到堆疊的下一個單元。通過AXD檢視暫存器和memory和暫存器中資料變化。

(2)在指令後面加上適當註釋,說明指令功能。

(3)指出程式執行完成後各相關暫存器及儲存器單元的具體內容。

五、實驗完成情況

1、實驗原始碼(含註釋):

assembly AREA Init,CODE,READONLY ;偽指令AREA定義名為Init,屬性為只讀或的程式碼片段 ENTRY ;偽指令ENTRY宣告程式入口 CODE32 ;宣告以下程式碼為 32 位 ARM 指令 x EQU 45 y EQU 64 ;定義兩個變數 x,y stack_top EQU 0x1000 ;定義堆疊地址 0x1000 start MOV SP, #stack_top ;設定棧頂地址 MOV R0, #x ;把x的值賦給R0 STR R0, [SP] ;R0中的內容入棧 MOV R0, #y ;把y的值賦給R0 LDR R1, [SP] ; 資料出棧,放入R1,即R1中放x的值 ADD R0, R0, R1 ;R0=R0+R1 STR R0, [SP,#4] ;先執行SP+4(ARM為32位指令集),再將R0內容複製到SP指向的暫存器 B . END ;程式結束

2、實驗過程(含結果截圖及相應文字解釋):

根據程式碼可知,

1.首先執行start MOV SP, #stack_top 通過該語句設定了棧頂地址為0x1000。

2.然後執行MOV R0, #x,把x的值賦值給了R0暫存器,此時R0暫存器的值變成45,由於是十六進位制儲存的,因此顯示為2D。

3.然後執行STR R0, [SP],將R0的值入棧,由於前面已經設定了棧頂地址為0x1000,因此可以檢視到記憶體地址0x100處的資料變成了2D。

4.然後執行MOV R0, #y,把y的值賦值給了R0暫存器,此時R0暫存器的值變成64,由於是十六進位制儲存的,因此顯示為40。

5.然後執行LDR R1, [SP],該資料出棧,將資料賦值給R1,此時R1中儲存的值為2D。

6.然後執行ADD R0, R0, R1,其含義相當於R0=R0+R1,因此R0暫存器的值為2D+40 = 6D。

7.最後執行STR R0, [SP, #4],先執行SP+4,將指標進行偏移,再將R0的值複製到此時SP指向的地址0x1004,該資料賦值為6D。

最後程式執行完成後各相關暫存器及儲存器單元的具體內容如下:

暫存器:

  • R0內容為0x6D,
  • R1內容為0x2D,
  • SP內容為0x1000,

儲存器單元:

  • 0x1000內容為0x2D,
  • 0x1004內容為0x6D。

練習題

編寫程式實現對一段資料的最大值最小值搜尋,最大值存於max變數之中,最小值存於min變數之中。

提示: 資料的定義採用偽指令:DCD來實現,如:

assembly DataBuf DCD 11,-2,35,47,96,63,128,-23

搜尋最大值和最小值可以利用兩個暫存器R1,R2來存放。用到的比較指令為CMP,用到的條件識別符號小於為LT,大於為GT。

基本思路為:利用R0做基地址,將R1,R2分別存入第一個單元的內容,利用R3做迴圈計數器,利用R4遍歷讀取第2至最後一個數據,如果R1的資料小於新讀入的R4資料則將R4的內容存入R1, 如果R2的內容大於R4的內容則將R4的內容存入R2。遍歷完成之後,R1將存放最大資料,R2將存放最小資料。

assembly AREA comp,CODE,READONLY ;定義CODE片段comp 只讀 ENTRY ;進入程式 CODE32 ;以下為32位的ARM程式 START LDR R0, = DAT ;載入資料段中DAT的資料的地址到R0 LDR R1, [R0] ;載入R0的內容到R1 LDR R2, [R0] ;載入R0的內容到R1 MOV R3,#1 ;設定迴圈變數R3並初始化為1 LOOP ADD R0,R0,#4 ;每次迴圈R0+4 LDR R4,[R0] ;R4存入R0的資料 CMP R1,R4 ;比較R1,R4 MOVLT R1,R4 ;如果R1<R4 就把R4存入R1 CMP R2,R4 ;比較R2,R4 MOVGT R2,R4 ;如果R2>R4 就把R4存入R2 ADD R3,R3,#1 ;每次迴圈R3值加一 CMP R3,#8 ;判斷R3與8 BLT LOOP ;如果R3 < 8則跳轉到LOOP執行 B . ;退出 AREA D,DATA,READONLY ;定義一個數據段D,讀寫 DAT DCD 11,-2,35,47,96,63,128,-23 END

實驗結果如下:

程式的基本思路是將DataBuf的首地址裝載到R0中,再通過首地址將第一個資料裝載到R1和R2中,設定R3為迴圈變數,並且初始化為1。然後進入迴圈,通過迴圈比較,將比較過程中得到的最大值放在R1中,最小值放在R2中,每一次迴圈R3中的值加1,當R3=8時,比較迴圈結束。


歡迎關注公眾號【AIShareLab】,一起交流更多相關知識,前沿演算法,Paper解讀,專案原始碼,面經總結。