體會KEIL5資料處理和傳輸過程

Saint發表於2018-10-26

作者:毛蘢瑋 / Saint

掘金:juejin.im/user/5aa1f8…

微博:weibo.com/5458277467/…

GitHub :github.com/saint-000

test1.1ARM資料處理指令定址方式實驗和ARM記憶體訪問指令定址方式實驗中程式碼如下:

體會KEIL5資料處理和傳輸過程

體會KEIL5資料處理和傳輸過程

通過除錯可以發現知道程式碼中的資料傳送指令MOV;算術運算指令-加法指令ADD和減法指令SUB;以及比較指令CMP等資料處理指令在暫存器的數值和地址的變化,初步瞭解ARM的定址方式以及資料傳送方式。

test1.2程式設計實現1+2+…+N 程式碼書寫:

;功能:計算1+2+3+4+...+N
;說明;N>=0,當N=0時結果為0,當N=1時結果為1
N EQU 100   ;定義N的值100
	AREA Examples,CODE,READONLY   ;宣告程式碼斷Examples3
	ENTRY   ;標識程式入口 
	
	CODE32
ARM_CODE
LDR SP,=0X30003F00    ;設定堆疊指標
	ADR R0,THUMB_CODE+1    
	BX R0        ;跳轉並切換處理器狀態
	LTORG        ;宣告文字池	
CODE16
THUMB_CODE
LDR R0,=N    ;設定子程式SUM_N的入口引數 
	BL SUM_N     ;呼叫子程式SUM_N
	B THUMB_CODE 
	
;SUM_N
;功能:計算1+2+3+......+N
;入口引數:R0 N的值
;出口引數:R0 執行結果 
;佔用資源:R0
;說明:當N=0時結果為0,當N=1時結果為1
;若運算溢位,結果為0
SUM_N
	PUSH {R1-R7,LR}  ;暫存器入棧保護
	MOVS R2,R0       ;將n的值複製到R2,並影響相應條件標誌
	BEQ SUM_END      ;若N=0,則返回,成立即返回
	CMP R2,#1		 ;比較R2是否為1
	BEQ SUM_END      ;若N=1,則返回,成立即返回
	MOV R1,#1        ;初始化計數器R1=1									MOV R0,#0        ;初始化計數器R0=0 
SUN_L1
	ADD R0,R1		 ;R0=R1+R0
	BVS SUM_END		 ;溢位	
	CMP R1,R2		 ;比較R1和n是否相等
	BVS SUM_END		 ;相等,跳出迴圈,即加到n結束
	ADD R1,#1		 ;R1=R1+1;
	B SUN_L1		 ;跳轉迴圈
SUM_ERR
	MOV R0,#0		;R0=0
SUM_END 
	MOV R8,R0		 ;將結果儲存在R8中
	POP {R1-R7,PC}   ;暫存器出棧,返回
        
	END
複製程式碼

結果: 最終暫存器R8的讀數為為0X000013BA,數值為十進位制的5050,正好是從1加至100之和,所以成功實現該功能。

test1.3理解C和彙編,並用彙編程式實現字串拷貝,並在C程式中呼叫該彙編程式。

在C程式中呼叫該彙編程式:

;檔名:main.c
;功能:完成字串的拷貝
#include <stdio.h>
extern void strcopy(char *d ,char *s);
int main(void)
{
	char *srcstr = "aaaa";
	char dststr[] = "bbbb";
	//printf("Before copying:\n");				//模擬除錯時禁用printf語句
	//printf(" %s %s\n",srcstr,dststr);
	strcopy(dststr,srcstr);
	//printf("After copying: \n");
	//printf(" %s\n  %s\n",srcstr,dststr);
	return (0);

}
複製程式碼

在彙編程式中:

;檔名:TEST.S 
;功能:從C語言中呼叫匯編語言
AREA	Example1,CODE,READONLY	;宣告程式碼段Example1 
CODE32				   ;宣告32位ARM指令
IMPORT __main
EXPORT strcopy
strcopy	
	LDRB  R2,[R1],#1	;拷貝源字串的一個位元組
	STRB  R2,[R0],#1	;將拷貝的位元組複製到目標空間,
	CMP   R2,#0		;比較R2=0
	BNE   strcopy	
	MOV   PC,LR
	END			     	  

複製程式碼

結果: 將原來的aaaa bbbb的值變成了aaaa aaaa,所以成功實現字串複製。

體會KEIL5資料處理和傳輸過程

體會KEIL5資料處理和傳輸過程

test1.4在彙編中呼叫C函式

;檔名:main.c
;功能:完成求和
int g(int a, int b ,int c,int d)
{
	return a+b+c+d;
}

;檔名:TESTFILE.S 
;功能:從組合語言中呼叫C語言
		IMPORT g
AREA	Example1,CODE,READONLY	  	
		CODE32				  	
		ENTRY
START	
		MOV		R0,#1	
		MOV		R1,#2
		MOV		R2,#3
		MOV		R3,#10
		BL		g
		MOV		R8,R0	
		B		START

		END

複製程式碼

結果: 最終暫存器R8讀數為0X000010,正好為1+2+3+10=16,所以正確實現該功能。

test1.5用ARM彙編實現冒泡演算法。

 AREA Sort,CODE,READONLY
	ENTRY
start
	MOV r4,#0
	LDR r6,=src
	ADD r6,r6,#len
outer
	LDR r1,=src
inner
  LDR r2,[r1]
  LDR r3,[r1,#4]
  CMP r2,r3
  STRGT r3,[r1]
  STRGT r2,[r1,#4]
  ADD r1,r1,#4
  CMP r1,r6
  BLT inner
  
  ADD r4,r4,#4
  CMP r4,#len
  SUBLE r6,r6,#2
  BLE outer
src DCD 2,4,10,8,14,1,20
    AREA Array,DATA,READWRITE
len EQU 7*4
	END
複製程式碼

結果: 從起始暫存器位置開始,每個四個輸出一個資料,資料依次為1,2,4,8,10,14,20,由此完成了氣泡排序法。    

體會KEIL5資料處理和傳輸過程
心得: (1)在寫氣泡排序過程中發現,如果使用雜項偽命令AREA定義資料段時, AREA Sort,CODE,READONLY這段程式碼要縮排,以及跟下面結束時的相同程式碼對齊,否則會出現編譯錯誤。

體會KEIL5資料處理和傳輸過程
(2)我們在使用memory map的時候,需要檢視同一個暫存器的首地址和尾地址的資料變化,我們需要將程式剛開始的暫存器首地址和結束時的尾地址填入memory map中,注意格式如下:

體會KEIL5資料處理和傳輸過程

體會KEIL5資料處理和傳輸過程

思考:

1.ADD替換成ADDS,SUB替換成SUBS有什麼影響?

運算結果不影響CPSR中相應標誌位的值,跳轉指令因為上一步的CPSR的值沒有改  
變而無法正確執行。S用於決定指令的操作是否影響CPSR中的條件標誌位。
複製程式碼

2.MOV替換成MOVNE有什麼影響?

只有在上一步計算結果為不相等時才執行。MOVNE先判斷條件NE (不相等)則轉移,可以看作是兩條指令NE=NOT EQUAL不相等。
複製程式碼

3.STMIA換成STMIB,STMIA換成STMDA有什麼區別?

STMIA換成STMIB是將每次寫入前地址+4改為地址-4,STMIA換成STMDA是將每次寫入前地址+4改為+1 ,其中STMIB(地址先增而後完成操作)、STMFA(滿遞增堆疊);
STMIA(完成操作而後地址遞增)、STMEA(空遞增堆疊);STMDB(地址先減而後完成操作)、STMFD(滿遞減堆疊);STMDA(完成操作而後地址遞減)、STMED(空遞減堆疊)。
複製程式碼

4.思考用ARM彙編實現1+3+5+…+(2n+1)或者2+4+6+…+2n。

實現1+3+5+„.+(2n+1):   
將 add r1,r1,#1 改為 add r1,r1,lsl  #1       sub r1,r1,#1   
實現2+4+6+…..+2n:   
將 add r1,r1,#1 改為 add r1,r1,lsl  #1  
複製程式碼

5.實驗3中如果去除彙編程式碼中的“EXPORT strcopy”會有什麼現象,為什麼?

C語言無法呼叫用strcopy函式。因為EXPORT偽指令用於在程式中宣告一個全域性的標  
號,該標號可在其他的檔案中引用。
複製程式碼

6.實驗4中如果去除彙編程式碼中的“IMPORT …..”會有什麼現象,為什麼?

體會KEIL5資料處理和傳輸過程

把“IMPORT ….註釋後發現,編譯除錯時程式單步執行直接從彙編程式開始,說明無法呼叫C語言的main函式。IMPORT偽操作告訴編譯器當前的符號不是在本原始檔中定義的,而是在其他原始檔中定義的,在本原始檔中可能引用該符號,而且不論本原始檔是否實際引用該符號,該符號都將被加入到本原始檔的符號表中。
複製程式碼

相關文章