嵌入式原理实验代码集合
============================================================= 实验一 AREA Examplel,CODE,READONLY;声明代码段 ENTRY ;标识程序入口 CODE32 ;声明32位ARM指令 START MOV R0,#15 ;设置参数 MOV R1,#8 ADDS R0,R0,R1 ;R0=R0+R1 B START END =========================================================================
实验二
=========================================================================
实验二  汇编指令实验1
COUNT EQU 0x40003100                  ;定义一个变量,地址为0x40003100
      AREA Example2,CODE,READONLY     ;声明代码段Example2
      ENTRY                           ;标识程序入口
      CODE32                          ;声明32位ARM指令
START LDR R1,=COUNT                   ;R1<=COUNT
      MOV R0,#0                       ;R0<=0
      STR R0,[R1]                     ;[R1]<=R0
LOOP  LDR R1,=COUNT
      LDR R0,[R1]                     ;R0<=[R1]
      ADD R0,R0,#1                    ;R0<=R0+1
      CMP R0,#10                      ;R0与10比较,影响条件码标志
      MOVHS R0,#0                     ;若R0大于等于10.执行R0<=0
      STR R0,[R1]                     ;[R1]<=R0,即保存COUNT
      B  LOOP
      END
实验二思考题:

思考题:第五题: COUNT EQU 0x40003400 ;定义一个变量,地址为0x40003400 AREA Example2,CODE,READONLY ;声明代码段Example2 ENTRY ;标识程序入口 CODE32 ;声明32位ARM指令 START LDR R1,=COUNT ;R1<=COUNT MOV R0,#80 ;R0<=80 STR R0,[R1] ;[R1]<=R0 LOOP LDR R1,=COUNT LDR R0,[R1] ;R0<=[R1] SUB R0,R0,#2 ;R0<=R0-2 CMP R0,#60 ;R0与60比较,影响条件码标志 MOVLO R0,#80 ;若R0大于等于60.执行R0<=80 STR R0,[R1] ;[R1]<=R0,即保存COUNT B LOOP END

思考题第六题 COUNT EQU 0x40003400 ;定义一个变量,地址为0x40003400 AREA Example2,CODE,READONLY ;声明代码段Example2 ENTRY ;标识程序入口 CODE32 ;声明32位ARM指令 START LDR R1,=COUNT ;R1<=COUNT LDR R0,=0xAA11BB22 ;R0<=0xAA11BB22 STR R0,[R1] ;[R1]<=R0 LDR R1,=COUNT LDR R0,[R1] LDRH R0,[R1] LDRSH R0,[R1] LDRB R0,[R1] LDRSB R0,[R1] LDR R0,=0xFFFFFFCC STRB R0,[R1] STRH R0,[R1] STR R0,[R1] B START END
实验三 汇编指令实验2

X EQU 11 ; 定义X的值为11 Y EQU 8 ; 定义Y的值为8 BIT23 EQU (1<<23) ; 定义BIT23的值为0x00800000 AREA Example3,CODE,READONLY ; 声明代码段Example3 ENTRY ; 标识程序入口 CODE32 ; 声明32位ARM指令 START ; 使用MOV、ADD指令实现:R8 = R3 = X + Y MOV R0,#X ; R0 <= X,X的值必须是8位图数据 MOV R1,#Y ; R1 <= Y,Y的值必须是8位图数据 ADD R3,R0,R1 ; 即是R3 = X + Y MOV R8,R3 ; R8 <= R3 ; 使用MVN、SUB指令实现:R5 = 0x5FFFFFF8 - R8 * 8 MVN R0,#0xA0000007 ; 0xA0000007的反码为0x5FFFFFF8 SUB R5,R0,R8,LSL #3 ; R8左移3位,结果即是 R8 * 8 ; 使用CMP指令判断(5*Y/2)>(2*X)吗?若大于则R5 = R5&0xFFFF0000,否则R5 = R5|0x000000FF MOV R0,#Y ADD R0,R0,R0,LSL #2 ; 计算R0 = Y + 4*Y = 5*Y MOV R0,R0,LSR #1 ; 计算R0 = 5*Y/2 MOV R1,#X MOV R1,R1,LSL #1 ; 计算R1 = 2*X CMP R0,R1 ; 比较R0和R1,即(5*Y/2)和(2*X)进行比较 LDRHI R2,=0xFFFF0000 ; 若(5*Y/2)>(2*X),则R2 <= 0xFFFF0000 ANDHI R5,R5,R2 ; 若(5*Y/2)>(2*X),则R5 = R5&R2 ORRLS R5,R5,#0x000000FF ; 若(5*Y/2)≤(2*X),则R5 = R5|0x000000FF ; 使用TST指令测试R5的bit23是否为1,若是则将bit6位清零(使用BIC指令) TST R5,#BIT23 BICNE R5,R5,#0x00000040 B START END
实验三思考题:
思考题1:不正确,直接带入,不符合图8位

 AREA Example4,CODE,READONLY;声明代码段 Example4
        ENTRY;
        CODE32    ;声明32位ARM指令
START   
		LDR R2,=0x1234
		LDR R3,=0x5678
		LDR R5,=0x9ACD
		LDR R6,=0xEF12
		ADDS R5,R2,R5;
		ADC  R6,R3,R6;
		B  START
		END

X        EQU        11            ; 定义X的值为11
Y        EQU        8            ; 定义Y的值为8
BIT23    EQU        (1<<23)        ; 定义BIT23的值为0x00800000
            
            AREA    Example3,CODE,READONLY    ; 声明代码段Example3
            ENTRY                ; 标识程序入口
            CODE32                ; 声明32位ARM指令
            
START        ; 使用MOV、ADD指令实现:R8 = R3 = X + Y
            MOV        R0,#X        ; R0 <= X,X的值必须是8位图数据
            MOV        R1,#Y        ; R1 <= Y,Y的值必须是8位图数据
            ADD        R3,R0,R1    ; 即是R3 = X + Y
            MOV        R8,R3        ; R8 <= R3
            
            
            ; 使用MVN、SUB指令实现:R5 = 0x5FFFFFF8 - R8 * 8
            MVN        R0,#0xA0000007        ; 0xA0000007的反码为0x5FFFFFF8
            SUB     R5,R0,R8,LSL #3        ; R8左移3位,结果即是 R8 * 8
        
            
            ; 使用CMP指令判断(5*Y/2)>(2*X)吗?若大于则R5 = R5&0xFFFF0000,否则R5 = R5|0x000000FF
            MOV        R0,#Y
            ADD        R0,R0,R0,LSL #2       
            MOV        R0,R0,LSR #1        
            MOV        R1,#X
            MOV        R1,R1,LSL #1      
            CMP        R0,R1               
            LDRLS    R2,=0xFFFF0000;      
            ANDHI    R5,R5,#0x000000FF;           
            ORRLS    R5,R5,R2
            
            B        START
            
            END    

X EQU 200 ; 定义X的值为11 Y EQU 163 ; 定义Y的值为8 BIT23 EQU (1<<23) ; 定义BIT23的值为0x00800000 AREA Example3,CODE,READONLY ; 声明代码段Example3 ENTRY ; 标识程序入口 CODE32 ; 声明32位ARM指令 START ; 使用MOV、RSB指令实现:R8 = R3 = X - Y MOV R0,#X ; R0 <= X,X的值必须是8位图数据 MOV R1,#Y ; R1 <= Y,Y的值必须是8位图数据 RSB R3,R0,R1 ; 即是R3 = X-Y MOV R8,R3 ; R8 <= R3 ;R5=R8*5-0x123 ADD R8,R8,R8,LSL #2;R8=R8+4*R8=5R8 LDR R2,=0x123; SUB R5,R8,R2; ; 使用CMP指令判断(4*Y/3+30)>(3*X-20)吗?若大于则R5 = R5&0xFF0000FF,否则R5 = R5|0x00FF0000 MOV R0,#Y/3 MOV R0,R0,LSL #2 ADD R0,R0,#30 MOV R1,#X ADD R1,R1,R1,LSL #1 SUB R1,R1,#20; CMP R0,R1 ; 比较R0和R1 LDRHI R2,=0xFF0000FF ; 若断(4*Y/3+30)>(3*X-20)则R2 <= 0xFF0000FF ANDHI R5,R5,R2 ; 若(4*Y/3+30)>(3*X-20),则R5 = R5&R2 ORRLS R5,R5,#0x00FF0000 ; 若(4*Y/3+30)<=(3*X-20),则R5 = R5|0x00FF0000 B START END
实验四 汇编指令实验3
实验的目的
使用ARM汇编指令实现结构化程序编程
1 使用ARM汇编指令实现 if 条件执行
2 使用ARM汇编指令实现 for 循环结构
3 使用ARM汇编指令实现 while 循环结构
4 使用ARM汇编指令实现 do...while 循环结构
5 使用ARM汇编指令实现 switch 开关结构
1 使用ARM汇编指令实现 if 条件执行
第一个案例 if结构 ;if(x>y) ; z=100; ;else ; z=50; ;设x为R0,y为R1,z为R2(x,y,z均为无符号整数) AREA Example4,CODE,READONLY;声明代码段 Example4 ENTRY;
CODE32 ;声明32位ARM指令 START MOV R0,#76;初始化x的值 MOV R1,#234;初始化y的值 CMP R0,R1;判断x>y MOVHI R2,#100;x>y条件正确,z=100 MOVLS R2,#50;条件失败,z=50
2 使用ARM汇编指令实现 for 循环结构
二案例 for结构 ;forIi==0;i<10;i++) ;{ ;x++ ;} ;设x为R0,i为R2(i,x均为无符号整数) AREA Example5,CODE,READONLY;声明代码段 Example5 ENTRY;
CODE32 ;声明32位ARM指令 MOV R0,#0;初始化x的值 MOV R2,#0;设置i=0 FOR_L1 CMP R2,#10;判断i<10? BHS FOR_END;若条件失败,退出循环 ADD R0,R0,#1;循环体,X++ ADD R2,R2,#1;i++ B FOR_L1 FOR_END NOP
3 使用ARM汇编指令实现 while 循环结构
第三个案例 while结构 ;while(x<y) ;{ ;x*=2 ;} ;设x为R0,y为R1(x,y均为无符号整数) AREA Example6,CODE,READONLY;声明代码段 Example6 ENTRY;
CODE32 ;声明32位ARM指令 MOV R0,#1;初始化x的值 MOV R2,#20;初始化y的值 B WHILE_L2;首先要盘判断条件 WHILE_L1 MOV R0,R0,LSL #1;循环体,x*=2 WHILE_L2 CMP R0,R1;判断x<=y BLS WHILE_L1;若条件正确,继续循环 WHILE_END NOP
4 使用ARM汇编指令实现 do...while 循环结构
第四个案例 do....while()结构 ;do ;{ ;x--; ;}while(x>0) ;设x为R0,(x为无符号整数) AREA Example6,CODE,READONLY;声明代码段 Example6 ENTRY;
CODE32 ;声明32位ARM指令 MOV R0,#5;初始化x的值 DOWHILE_L1 ADD R0,R0,#-1;循环体,x--; DOWHILE_L2 MOVS R0,R0;R0<=R0,并且影响条件标志 BNE DOWHILE_L1;若R0不为0(即x不为0)继续循环 DOWHILE_END NOP
5 使用ARM汇编指令实现 switch 开关结构
第五个案例 switch ;switch(key&0x0F) ;{ ; case 0: ; case 2: ; case 3:x=key+y; ; break; ; case 5:x=key-y; ; break; ; case 7:x=key*y; ; break; ; default x=168; ; break; ;} ;设x为R0,y为R1,key为R2(x,y,key均为无符号整数) AREA Example6,CODE,READONLY;声明代码段 Example6 ENTRY;
CODE32 ;声明32位ARM指令 MOV R1,#3;初始化y的值 MOV R2,#2;初始化key的值 SWITCH AND R2,R2,#0x0F;switch(key&0x0F) CASE_0 CMP R2,#0;case 0: CASE_2 CMPNE R2,#2;case 2: CASE_3 CMPNE R2,#3;case 3: BNE CASE_5 ADD R0,R2,R1;x=key+y B SWITCH_END;break; CASE_5 CMP R2,#5;case 5: BNE CASE_7 SUB R0,R2,R1;x=key-y B SWITCH_END;break; CASE_7 CMP R2,#7;case 7: BNE DEFAULT MUL R0,R2,R1;x=key*y B SWITCH_END;break DEFAULT MOV R0,#168;default x=168 SWITCH_END NOP HALT B HALT END
实验四思考题:

;if(x>80){ ; if(x>90){ ; z=4; ; }else{ ; z=3; ; } ;}else{ ; if(x>70){ ; z=2; ; }else{ ; if(x>=60) z=1; else z=0; ; } ;} ;设x为R0,z为R2(x,z均为无符号整数) AREA Example4,CODE,READONLY;声明代码段 Example4 ENTRY; CODE32 ;声明32位ARM指令 START MOV R0,#76;初始化x的值 CMP R0,#80;x与80比较 BHS IF_L1;大于或者等于80的时候 BLO IF_L2;小于80的时候 IF_L1 CMP R0,#90;x与90比较 MOVHS R2,#4;大于等于90的时候对z=4 MOVLO R2,#3;大于80小于90的时候z=3 IF_L2 CMP R0,#70;x与70比较 MOVHS R2,#2 CMPLO R0,#60; MOVHS R2,#1; MOVLO R2,#0;
HALT     B HALT
         END

思考题3:if结构
;if(a==b) c=100; ;else c=50; ;设a为R0,b为R1,c为R2 ;a,b,c均为无符号整数 AREA Example4,CODE,READONLY;声明代码段 Example4 ENTRY; CODE32 ;声明32位ARM指令 START MOV R1,#3;初始化y的值 MOV R2,#2;初始化key的值 CMP R0,R1;判断a==b MOVEQ R2,#100; MOVHE R2,#50;
思考题3:for结构
;for(x=0;i=5;i>0;i--) ;{ ;x=x+i; ;} ;设x为R0,i为R2(i,x均为无符号整数) AREA Example4,CODE,READONLY;声明代码段 Example4 ENTRY; CODE32 ;声明32位ARM指令 START MOV R0,#0;初始化x的值 MOV R2,#5;初始化i FOR_L1 CMP R2,#0;i>0? BLS FOR_END; ADD R0,R0,R2; SUB R2,R2,#1; B FOR_L1 FOR_END NOP
思考题3:while()结构
;x=0;y=0; ;while(x<10) ;{ ; y=y+x; ; x++; ;} ;设x为R0,y为R1(x,y均为无符号整数) AREA Example4,CODE,READONLY;声明代码段 Example4 ENTRY; CODE32 ;声明32位ARM指令 START MOV R0,#0; MOV R1,#0; B WHILE_L1;首先要盘判断条件 WHILE_L1 ADD R1,R0,R1; ADD R0,R0,#1; WHILE_L2 CMP R0,#10; BLO WHILE_L1; WHILE_END NOP;
思考题3:swith()结构
;x=1; ;switch(x){ ; case 0:y=0;break; ; case 1:y=1;break; ; case 2:y=2;break; ; default:y=3;break; ;} ;设x为R0,y为R1(x,y均为无符号整数) AREA Example4,CODE,READONLY;声明代码段 Example4 ENTRY; CODE32 ;声明32位ARM指令 START MOV R0,#1; SWITCH CASE_0 CMP R0,#0; ENE CASE_1 MOV R1,#0; B SWITCH_END CASE_1 CMP R0,#1; BNE CASE_2 MOV R1,#1; B SWITCH_END CASE_2 CMPNE R0,#2; BNE DEFAULT MOV R1,#2; B SWITCH_END DEFAULT MOV R1,#3; SWITCH_END
实验五
;定义堆栈的大小
USR_STACK_LEGTH     EQU         64
SVC_STACK_LEGTH     EQU         0
FIQ_STACK_LEGTH     EQU         16
IRQ_STACK_LEGTH     EQU         64
ABT_STACK_LEGTH     EQU         0
UND_STACK_LEGTH     EQU         0
			AREA	Example5,CODE,READONLY	; 声明代码段Example5
			ENTRY				; 标识程序入口
			CODE32				; 声明32位ARM指令
START		MOV		R0,#0
			MOV		R1,#1
			MOV		R2,#2
			MOV		R3,#3
			MOV		R4,#4
			MOV		R5,#5
			MOV		R6,#6
			MOV		R7,#7
			MOV		R8,#8
			MOV		R9,#9
			MOV		R10,#10
			MOV		R11,#11
			MOV		R12,#12
			
			BL		InitStack	; 初始化各模式下的堆栈指针
			
			; 打开IRQ中断 (将CPSR寄存器的I位清零)
			MRS		R0,CPSR			; R0 <= CPSR
			BIC		R0,R0,#0x80 
			MSR		CPSR_cxsf,R0	; CPSR <= R0
						
			; 切换到用户模式
        	MSR     CPSR_c, #0xd0
        	MRS		R0,CPSR
        	
        	; 切换到管理模式
        	MSR     CPSR_c, #0xdf
        	MRS		R0,CPSR		
HALT		B		HALT
			
; 名称:InitStack
; 功能:堆栈初始化,即初始化各模式下的堆栈指针。
; 入口参数:无
; 出口参数:无
; 说明:在特权模式下调用此子程序,比如复位后的管理模式
InitStack    
        	MOV     R0, LR		; R0 <= LR,因为各种模式下R0是相同的
;设置管理模式堆栈
        	MSR     CPSR_c, #0xd3
        	LDR     SP, StackSvc
;设置中断模式堆栈
        	MSR     CPSR_c, #0xd2
        	LDR     SP, StackIrq
;设置快速中断模式堆栈
        	MSR     CPSR_c, #0xd1
        	LDR     SP, StackFiq
;设置中止模式堆栈
        	MSR     CPSR_c, #0xd7
      		LDR     SP, StackAbt
;设置未定义模式堆栈
        	MSR     CPSR_c, #0xdb
        	LDR     SP, StackUnd
;设置系统模式堆栈
        	MSR     CPSR_c, #0xdf
        	LDR     SP, StackUsr
        	MOV     PC, R0
StackUsr   	DCD     UsrStackSpace + (USR_STACK_LEGTH - 1)*4
StackSvc    DCD     SvcStackSpace + (SVC_STACK_LEGTH - 1)*4
StackIrq    DCD     IrqStackSpace + (IRQ_STACK_LEGTH - 1)*4
StackFiq    DCD     FiqStackSpace + (FIQ_STACK_LEGTH - 1)*4
StackAbt    DCD     AbtStackSpace + (ABT_STACK_LEGTH - 1)*4
StackUnd    DCD     UndtStackSpace + (UND_STACK_LEGTH - 1)*4
; 分配堆栈空间 
        	AREA    MyStacks, DATA, NOINIT, ALIGN=2
UsrStackSpace     	SPACE  	USR_STACK_LEGTH * 4 	; 用户(系统)模式堆栈空间
SvcStackSpace      	SPACE  	SVC_STACK_LEGTH * 4  	; 管理模式堆栈空间
IrqStackSpace      	SPACE  	IRQ_STACK_LEGTH * 4  	; 中断模式堆栈空间
FiqStackSpace      	SPACE  	FIQ_STACK_LEGTH * 4  	; 快速中断模式堆栈空间
AbtStackSpace      	SPACE  	ABT_STACK_LEGTH * 4  	; 中止义模式堆栈空间
UndtStackSpace     	SPACE  	UND_STACK_LEGTH * 4  	; 未定义模式堆栈			
			
			
			END	
实验六
Startup.s
; 起动文件。初始化C程序的运行环境,然后进入C程序代码。
      	IMPORT	|Image$$RO$$Limit|  
      	IMPORT	|Image$$RW$$Base|   
      	IMPORT	|Image$$ZI$$Base|   
        IMPORT	|Image$$ZI$$Limit|  
		IMPORT	Main		; 声明C程序中的Main()函数
		AREA	Start,CODE,READONLY	; 声明代码段Start
		ENTRY				; 标识程序入口
		CODE32				; 声明32位ARM指令	
			
Reset	LDR		SP,=0x40003F00
        ; 初始化C程序的运行环境
    	LDR	  	R0,=|Image$$RO$$Limit|
    	LDR	    R1,=|Image$$RW$$Base|	
    	LDR	    R3,=|Image$$ZI$$Base|	
			
    	CMP	  	R0,R1
    	BEQ	    LOOP1
LOOP0	CMP	    R1,R3	  
    	LDRCC   R2,[R0],#4     
    	STRCC   R2,[R1],#4 
    	BCC	    LOOP0
    	
LOOP1	LDR	    R1,=|Image$$ZI$$Limit| 
    	MOV	    R2,#0
LOOP2	CMP	    R3,R1
    	STRCC   R2,[R3],#4
    	BCC	    LOOP2
    	
    	B		Main		; 跳转到C程序代码Main()函数
    	
    	END
TEST.c
#define  uint8  	unsigned char 
#define  uint32 	unsigned int
#define  N		100
uint32  sum;
// 使用加法运算来计算1+2+3+...+(N-1)+N的值。(N>0)
void  Main(void)
{  uint32  i;
   
   sum = 0;
   for(i=0; i<=N; i++)
   {  sum += i;
   }
   
   while(1);
}
 
  
思考题:
1.作用:用于引导程序,特别是找到main函数的地址位置。程序从Startup.s中开始引导配置,直到找到main函数的地址后
再转到Main()函数中执行.c文件的代码。
会出错,程序运行的过程中找不到main函数的地址。
2.不能改,因为在Startup.s中“B MAIN”将程序跳转到mian函数中。如果改为其他的名字在寻址的过程中找不到相应的标号。
实验七:
; 起动文件。初始化C程序的运行环境,然后进入C程序代码。
      	IMPORT	|Image$$RO$$Limit|  
      	IMPORT	|Image$$RW$$Base|   
      	IMPORT	|Image$$ZI$$Base|   
        IMPORT	|Image$$ZI$$Limit|  
		IMPORT	Main		; 声明C程序中的Main()函数
		AREA	Start,CODE,READONLY	; 声明代码段Start
		ENTRY				; 标识程序入口
		CODE32				; 声明32位ARM指令	
			
Reset	LDR		SP,=0x40003F00
        ; 初始化C程序的运行环境
    	LDR	  	R0,=|Image$$RO$$Limit|
    	LDR	    R1,=|Image$$RW$$Base|	
    	LDR	    R3,=|Image$$ZI$$Base|	
			
    	CMP	  	R0,R1
    	BEQ	    LOOP1
LOOP0	CMP	    R1,R3	  
    	LDRCC   R2,[R0],#4     
    	STRCC   R2,[R1],#4 
    	BCC	    LOOP0
    	
LOOP1	LDR	    R1,=|Image$$ZI$$Limit| 
    	MOV	    R2,#0
LOOP2	CMP	    R3,R1
    	STRCC   R2,[R3],#4
    	BCC	    LOOP2
    	
    	B		Main		; 跳转到C程序代码Main()函数
    	
    	END
; 加法函数,原型为uint32 Add(uint32 x, uint32 y)。 EXPORT Add AREA AddC,CODE,READONLY ; 声明代码段AddC ENTRY ; 标识程序入口 CODE32 ; 声明32位ARM指令 Add ADD R0,R0,R1 ; 输入参数x为R0,y为R1 MOV PC,LR ; 返回值为R0 END
1.作用:用于引导程序,特别是找到main函数的地址位置。程序从Startup.s中开始引导配置,直到找到main函数的地址后
再转到Main()函数中执行.c文件的代码。
    一纸高中万里风,寒窗读破华堂空。
莫道长安花看尽,由来枝叶几相同?
 
                    
                
 
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号