体会KEIL5数据处理和传输过程

作者:毛茏玮 / Saint

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

微博:weibo.com/5458277467/…

GitHub :github.com/saint-000

test1.1ARM数据处理指令寻址方式实验和ARM内存访问指令寻址方式实验中代码如下:

通过调试可以发现知道代码中的数据传送指令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,所以成功实现字符串复制。

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,由此完成了冒泡排序法。    

心得: (1)在写冒泡排序过程中发现,如果使用杂项伪命令AREA定义数据段时, AREA Sort,CODE,READONLY这段代码要缩进,以及跟下面结束时的相同代码对齐,否则会出现编译错误。

(2)我们在使用memory map的时候,需要查看同一个寄存器的首地址和尾地址的数据变化,我们需要将程序刚开始的寄存器首地址和结束时的尾地址填入memory map中,注意格式如下:

思考:

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 …..”会有什么现象,为什么?

把“IMPORT ….注释后发现,编译调试时程序单步运行直接从汇编程序开始,说明无法调用C语言的main函数。IMPORT伪操作告诉编译器当前的符号不是在本源文件中定义的,而是在其他源文件中定义的,在本源文件中可能引用该符号,而且不论本源文件是否实际引用该符号,该符号都将被加入到本源文件的符号表中。
复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值