> 文章列表 > 汇编第二次上机实验(续第一次,字符串比较及双重循环)【嵌入式系统】

汇编第二次上机实验(续第一次,字符串比较及双重循环)【嵌入式系统】

汇编第二次上机实验(续第一次,字符串比较及双重循环)【嵌入式系统】

汇编第二次上机实验(续第一次,字符串比较及双重循环)【嵌入式系统】

  • 前言
  • 推荐
  • 说明
  • 汇编第二次上机实验(续第一次,字符串比较及双重循环)
    • 内容
    • 1 sort
      • 说明
      • 流程图
      • 代码编写
      • 结果分析
    • 2 string
      • 流程图
      • 代码编写
      • 结果分析
    • 3 Bibble
      • 流程图
      • 代码编写
      • 结果分析
    • 4 factorial
      • 流程图
      • 代码编写
      • 结果分析
    • 5 略
  • 最后

前言

2023-4-14 21:29:03

以下内容源自《创作模板三》
仅供学习交流使用

推荐

ARM汇编第一次上机(顺序、分支、单重循环)【嵌入式系统】

说明

请见ARM汇编第一次上机(顺序、分支、单重循环)【嵌入式系统】说明

汇编第二次上机实验(续第一次,字符串比较及双重循环)

内容

按照要求编程实现以下功能,简要写出设计思路,画出程序流程图,并把调试结果截图附录,提交实验报告。
录制上传视频,演示实验并讲述主要过程。(10分钟左右视频)

1、修改排序程序,按照字节方式排序,画出编程思路及程序流程。(5分)
2、编程实现统计任意两个字符串各自包含的字符个数的功能,约定字符串以0为结束标志,然后对这两个字符串判断是否匹配(是否一致)?灵活一点可以给定3个字符串,然后进行比较。(基本功能8分,字符统计4分,字符串比较4分)
3、课本第11题,参考冒泡排序程序完成编程与调试(7分)
4、编写一个求阶乘 N!的 ARM 汇编程序,给定N 值(10~20中间取值),然后完成求和运算:SUM=1!+2!+…+N!。(5分)
5、附加功能,结合C语言,在第4题基础上增加输入、输出人机交互功能,根据输入字符统计字符个数并比较输入的字符串是否匹配,打印显示结果。(10分)

1 sort

说明

第一点 为什么拷贝数组

首先,Keil4会把READWITER区初始化为0
其次,原始数据放到READONLY区,将不能改变
所以,要把原数数据(READONLY)拷贝到拷贝数组(READWITER)中,进行排序

第二点指针的计算

	LDR	R1,=nums				; (右指针)R1起初指向src第一个单元	LDRB R4,  count         	; R4中是数据区中待排序数据个数SUB	R4,  R4,  #1			; R4--ADD	R1,R1,R4				;(右指针)R1指向src最后一个单元 R1=R1+R4*1,

参见如下C语言

此处,不做过得解释

#include<stdio.h>
int main(){int nums[10]={0,1,2,3,4,5,6,7,8,9};int *p=nums;//nums[0]的地址 printf("%x\\n",p);//62fdf0p=p+9;//nums[9]的地址 printf("%x\\n",p);//62fe14printf("%d\\n",*p);//9
} //地址计算 //0x62fdf0+36=0x62fe14//address9=address0+9*sizeof(int) //sizeof(int) =4

流程图

此处简画流程图

知道冒泡排序的思想即可

在这里插入图片描述

具体实现
可以结合注释
查看代码即可

代码编写

	AREA sort, CODE, READONLYENTRY
start;实现数组拷贝 需要输入原数组 数组长度 输出目的数组 即可LDR R1,=nums0        	; R1指向数据区的源字符串LDR R0,=nums        	; R0指向数据区的目的字符串LDRB R3,count			;数组个数BL  numscopy            ; 调用子程序numscopy,完成数组拷贝LDR	R1,=nums				; (右指针)R1起初指向src第一个单元	MOV	R2,  #0					; 用于外层循环控制计数器,并初始化为0LDRB R4,  count         	; R4中是数据区中待排序数据个数SUB	R4,  R4,  #1			; R4--ADD	R1,R1,R4				;(右指针)R1指向src最后一个单元 R1=R1+R4*1,
outer						; 外层循环LDR	R0,  =nums				;(左指针)R0指向数据区src单元
inner						; 内层循环LDRB	R5,  [R0]				; 将R0所指向单元的数加载到R5中LDRB	R6,[R0, #1]				; 将相邻单元的数加载到R6中CMP	R5,  R6     			; 比较相邻两单元中的数STRBGT  R6,  [R0]  			;如果前者大于后者,那么两个数交换STRBGT  R5, [R0, #1]  	    ; 内层循环修改、控制部分ADD	R0,  R0,  #1  			; 地址指针向下拨移1个字节CMP	R0,  R1   				; 是否扫描了一遍BNE	inner 					; 没有完成一遍,继续内循环; 外层循环修改、控制部分,表示已经完成了一遍,ADD	R2,  R2,  #1		; 外层循环控制计数器加1SUB	R1,  R1,  #1		; 右指针R1向左指针方向移动1字节CMP	R2,  R4				; 是否全部扫描	BNE	outer				; 没有完成全部扫描,继续外循环
stopMOV R0,  #0x18  		; 程序结束返回编译器调试环境LDR		R1,  =0x20026SWI		0x123456numscopy 	LDRB     R2,     [R1],    #1    ; 将R1指向的单元内容加载到R2中STRB     R2,     [R0],    #1    ; 将R2中的数存储到R0指向的单元中SUBS    R3,R3,#1			   ;R3--CMP     R3,      #0            ; 检查R0的值是否等于0BNE     numscopy               ; 如果不等于0,那么转到strcopy处执行 MOV     PC,    LR              ; 子程序返回 AREA BlockData0, DATA, READONLY
nums0 DCB	1,2,3,4,5,9,8,7,6,0
count DCB	10AREA BlockData, DATA, READWRITE
nums DCB	1,2,3,4,5,9,8,7,6,0   ;Keil会把此数组初始化为0END

结果分析

数组拷贝

汇编第二次上机实验(续第一次,字符串比较及双重循环)【嵌入式系统】

初始化右指针

R1=0x40000009   //右指针指向数组的最右端
R2=0			//计算器
R4=9 			//外循环次数

汇编第二次上机实验(续第一次,字符串比较及双重循环)【嵌入式系统】

第一遍排序

R1=0x40000008	//右指针左移
R2=1			//计算器+1
R5,R6用于交换相邻数组元素

汇编第二次上机实验(续第一次,字符串比较及双重循环)【嵌入式系统】

排序完成

R2=R4=9

汇编第二次上机实验(续第一次,字符串比较及双重循环)【嵌入式系统】

2 string

流程图

汇编第二次上机实验(续第一次,字符串比较及双重循环)【嵌入式系统】

代码编写

		AREA  string ,CODE, READONLYENTRYCODE32
startLDR R1,=str1        ; R1指向数据区的源字符串1LDR R3,=0           ;暂存长度BL length			; 调用子程序length,完成求长度MOV R4,R3			;R4存str1的长度LDR R3,=0           ;暂存长度LDR R1,=str2        ; R1指向数据区的目的字符串2BL length           ; 调用子程序length,完成求长度MOV R5,R3			;R5存str2的长度LDR R1,=str1LDR R2,=str2 BL compareLDR R9,=eqstateSTRB R8,[R9]stopMOV     R0,     #0x18	         ; 程序结束返回编译器调试环境LDR      R1,     =0x20026SWI        0x123456;求字符串长度 输入R1 字符串起始地址 返回R3长度
length ADD R3,R3,#1				 ;R3++LDRB R2,     [R1,#1]!        ; 将R1+1指向的单元内容加载到R2中 先前1位搜索CMP  R2,    #0               ; 检查R2的值是否等于0BNE  length                  ; 如果不等于0,那么转到length处执行 MOV  PC,    LR               ; 子程序返回 ;比较字符串是否相等;输入R1 str1的地址 R4 str1的长度 R2 str2的地址 R5 str2的长度;输出 R8 比较结果 ;0表示不一样 1表示一样
compare		;比较长度是否相等CMP R4,R5MOVNE R8,#0MOVNE PC, LR        		; 子程序返回 MOV R4,#0					;作为计数
loop		LDRB R6,[R1],#1				;R6遍历str1LDRB R7,[R2],#1				;R7遍历str2		CMP R6,R7				;字符不相等MOVNE R8,#0				;即字符串不相等MOVNE PC,LR             ; 子程序返回 ADD R4,R4,#1			;计数器CMP R4,R5				;控制循环次数BNE loopMOV R8,#1				;遍历完 即为相等MOV PC,LR               ; 子程序返回 		AREA    Strings0, DATA, READONLY
str1  DCB "12345",0		; 源字符串1
str2  DCB "12345",0		; 源字符串2	AREA    Strings, DATA, READWRITE
eqstate DCB 0							;0表示不一样 1表示一样END 

结果分析

求长度

R4=5
R5=5

汇编第二次上机实验(续第一次,字符串比较及双重循环)【嵌入式系统】
比较结果

R8=1
[0x40000000]=0x01

汇编第二次上机实验(续第一次,字符串比较及双重循环)【嵌入式系统】

3 Bibble

流程图

与1相同

代码编写

	AREA Bibble, CODE, READONLYENTRY
start;想实现数组拷贝 需要输入原数组 数组长度 输出目的数组 即可;这里借用字符串拷贝 要求源数组最后加一个无效元素0 中间不能出现0LDR       R1,    =src0        	; R1指向数据区的源字符串LDR       R0,    =src        	; R0指向数据区的目的字符串BL          strcopy             ; 调用子程序strcopy,完成字符串拷贝LDR	R1,=src				; (右指针)R1起初指向src第一个单元	MOV	R2,  #0				; 用于外层循环控制计数器,并初始化为0LDR	R4,  num         	; R4中是数据区中待排序数据个数SUB	R4,  R4,  #1		;R4--ADD	R1,  R4,LSL #2			;(右指针)R1指向src最后一个单元 R1=R1+R4*4,
outer						; 外层循环LDR	R0,  =src				;(左指针)R0指向数据区src单元
inner						; 内层循环LDR	R5,  [R0]				; 将R0所指向单元的数加载到R5中LDR	R6,[R0, #4]				; 将相邻单元的数加载到R6中CMP	R5,  R6     			; 比较相邻两单元中的数STRGT  R6,  [R0]  			;如果前者大于后者,那么两个数交换STRGT  R5, [R0, #4]  	    ; 内层循环修改、控制部分ADD	R0,  R0,  #4  			; 地址指针向下拨移4个字节CMP	R0,  R1   				; 是否扫描了一遍BNE	inner 					; 没有完成一遍,继续内循环; 外层循环修改、控制部分,表示已经完成了一遍,ADD	R2,  R2,  #1		; 外层循环控制计数器加1SUB	R1,  R1,  #4		; 右指针R1向左指针方向移动4字节CMP	R2,  R4				; 是否全部扫描	BNE	outer				; 没有完成全部扫描,继续外循环
stopMOV R0,  #0x18  		; 程序结束返回编译器调试环境LDR		R1,  =0x20026SWI		0x123456strcopy LDR     R2,     [R1],    #4    ; 将R1指向的单元内容加载到R2中STR     R2,     [R0],    #4    ; 将R2中的数存储到R0指向的单元中CMP     R2,      #0            ; 检查R0的值是否等于0BNE     strcopy                ; 如果不等于0,那么转到strcopy处执行 MOV     PC,    LR              ; 子程序返回 AREA BlockData0, DATA, READONLY
src0 DCD	18,4,2,35,3,20,1,23,12,21,0		
num	DCD	10AREA BlockData, DATA, READWRITE
src	DCD	18,4,2,35,3,20,1,23,12,21,0   ;Keil会把此数组初始化为0END

结果分析

分析过了:略

4 factorial

流程图

在这里插入图片描述

代码编写

	AREA factorial, CODE, READONLYENTRY
start;迭代算法思想 把每个阶乘放到数组中 接着求和 避免阶乘的重复计算
;1!=1
;n!=n*(n-1)!LDR R0,n     			; R0是nLDR R1,=1        		; R1是计数器 1->nLDR R2,=nums			; R2指向numsSTR R1,[R2]				;放入1!ADD R1,R1,#1			;2开始
loopLDR R3,[R2]         	;R3=(n-1)!MUL R4,R1,R3            ;R4=n*(n-1)!STR R4,[R2,#4]!;		;存入ADD R1,R1,#1            ;R1++CMP R1,R0BLS loopLDR R0,n     			; R0是nLDR R1,=1        		; R1是计数器 1->nLDR R2,=nums			; R2指向nums	LDR R5,=sum				; R5指向sumLDR R6,=0				; R6存入sum
sumloopLDR R3,[R2],#4         ;R3取出遍历数组的值 ;R3=[R2++]ADD R6,R6,R3            ;R6+=R3ADD R1,R1,#1            ;R1++CMP R1,R0BLS sumloop	STR R6,[R5]				;存入stopMOV R0,  #0x18  		; 程序结束返回编译器调试环境LDR	R1,  =0x20026SWI	0x123456AREA BlockData0, DATA, READONLY
n   DCD	4AREA BlockData, DATA, READWRITE
nums DCD	1,2,3,4,5,9,8,7,6,0   ;Keil会把此数组初始化为0
sum DCD 0END

结果分析

当n=4时

求阶乘

01 02 06 18

汇编第二次上机实验(续第一次,字符串比较及双重循环)【嵌入式系统】

阶乘求和

01+02+06+18=21

汇编第二次上机实验(续第一次,字符串比较及双重循环)【嵌入式系统】
当n=10时

0x003D9D19=4037913

汇编第二次上机实验(续第一次,字符串比较及双重循环)【嵌入式系统】

5 略

最后

2023-4-14 23:40:30

你对我百般注视,并不能构成万分之一的我,却是一览无余的你。

祝大家逢考必过
点赞收藏关注哦