乐趣区

关于arm:嵌入式ARM设计编程二-字符串拷贝

文章和代码已归档至【Github 仓库:hardware-tutorial】,须要的敌人们自取。或者关注公众号【AIShareLab】,回复 嵌入式 也可获取。

一、试验目标

通过试验把握应用 LDB/STB,b 等指令实现较为简单的存储区拜访和程序分支,学习应用条件码

二、试验环境

硬件:PC 机

软件:ADS1.2 集成开发环境

三、试验内容

相熟开发环境的应用并实现一块存储区的拷贝。

实现分支程序设计,要求判断参数,依据不同参数,调用不同的子程序。

四、试验要求

  1. 依照 2.3 节介绍的办法, 在 ADS 下创立一个工程 asmlab2,定义两个数据存储区 Src 和 Dst,Src 用于寄存原字符串,Dst 用于寄存目标字符串。堆栈地址 0x400,将变量原字符串的内容拷贝到目标字符串中,要能判断原字符串的结束符(0),并统计字符串中字符的个数。通过 AXD 查看寄存器和 memory 和寄存器中数据变动。
  2. 在指令前面加上适当正文, 阐明指令性能。
  3. 指出程序执行实现后各相干寄存器及存储器单元的具体内容。

五、试验实现状况:

1、试验源代码(含正文):

AREA Init,CODE,READONLY ; 定义 CODE 片段 Init 只读
 ENTRY                ; 进入程序
 CODE32              ; 以下为 32 位的 ARM 程序
start
  MOV SP, #0x400     ; 设置堆栈地址为 0x400
  LDR R0, =Src        ; 先将原字符串地址加载到 R0
  LDR R1, =Dst        ; 将目标字符串地址加载到 R1
  MOV R3,#0         ; 定义 R3 中的内容为 0
strcopy
  LDRB R2,[R0],#1     ; 将 R0 的内容读入寄存器 R2,并将 R0R0+1
  CMP R2,#0         ; 比拟 R2 和 0 是否相等,次要检测字符串是否完结
  BEQ endcopy       ; 等于 0 则跳转至 endcopy
  STRB R2,[R1],#1     ; 先将 R2 中的字节数据写入 R1 中,并把地址 R1+ 1 的值存入 R1
  ADD R3,R3,#1       ; R3 自加一,用于记录字符个数
  B strcopy           ; 循环
endcopy
  LDR R0, =ByteNum   ; 将字符数的地址加载到 R0
  STR R3,[R0]         ; 将 R3 的内容存在 R0 中
  B .
  AREA Datapool,DATA,READWRITE  ; 定义 DATA 类型的 Datapool
Src  DCB  "string",0  ; 初始化字符串的存储空间
Dst DCB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0   ; 目标字符串存储空间
ByteNum DCD 0 ; 初始化字符数
 END

2、试验过程(含后果截图及相应文字解释):

定义两个数据存储区 Src 和 Dst,Src 用于寄存原字符串,Dst 用于寄存目标字符串。堆栈地址 0x400,将变量原字符串的内容拷贝到目标字符串中,要能判断原字符串的结束符(0),并统计字符串中字符的个数。通过 AXD 查看寄存器和 memory 和寄存器中数据变动。

通过存储器可见,内容正在逐步地进行拷贝。过程如下:

直到拷贝过程完结,试验完结后存储单元中的内容如下:

相干寄存器中的具体内容如下所示:

练习题:

编写程序循环对 R4~R11 进行累加 8 次赋值,R4~R11 起始值为 1~8,每次加操作后把 R4~R11 的内容放入 SP 栈中,SP 初始设置为 0x800。最初把 R4~R11 清空赋值为 0。

提醒:多字的加载与存储应用多寄存器寻址,应用的指令为 LDM 和 STM。如:

LDMIA R0!, {R4-R11}
STMIA R1!, {R4-R11}

编写试验代码如下:

  AREA Init,CODE,READONLY ; 定义 CODE 片段 Init 只读
 ENTRY    ; 进入程序
 CODE32    ; 以下为 32 位的 ARM 程序
main NOP
NUM EQU 8     ; 定义 NUM 为 8,即一共通过 8 次循环           
start
 MOV SP,#0X800;设置栈顶指针为 0X800
 LDR R0,=src            ; 将 src 的地址加载到 R0
 MOV R2,#NUM         ; 将循环次数赋给 R2
 MOV R4,#1                 ; 设置寄存器 R4 的初始值
 MOV R5,#2                ; 设置寄存器 R5 的初始值
 MOV R6,#3                ; 设置寄存器 R6 的初始值
 MOV R7,#4                ; 设置寄存器 R7 的初始值
 MOV R8,#5                ; 设置寄存器 R8 的初始值
 MOV R9,#6                ; 设置寄存器 R9 的初始值
 MOV R10,#7            ; 设置寄存器 R10 的初始值
 MOV R11,#8            ; 设置寄存器 R11 的初始值    
loop
 ADD R4,R4,#1            ; 将寄存器的值加一,下同
 ADD R5,R5,#1
 ADD R6,R6,#1
 ADD R7,R7,#1
 ADD R8,R8,#1
 ADD R9,R9,#1
 ADD R10,R10,#1
 ADD R11,R11,#1    
 STMFD SP!,{R4-R11}      ; 多寄存器寻址,把 R4~R11 的内容放入 SP 栈中
 SUBS R2,R2,#1           ; 将 R2 的内容,即循环次数减一
 BNE loop                ; 如果不为 0 则跳转到 loop 持续循环    
 LDMIA R0!,{R4-R11}      ; 将以 R0 起始地址的值存入 R4-R11,即把 R4~R11 清空赋值为 0.
Stop
 B Stop
 LTORG                   ; 申明数据缓冲池
src DCD 0,0,0,0,0,0,0,0       ; 初始化
 END

试验初始时,寄存器中内容如下:

试验完结后,寄存器中的内容如下:


欢送关注公众号【AIShareLab】,一起交换更多相干常识,前沿算法,Paper 解读,我的项目源码,面经总结。

退出移动版