嵌入式ARM设计编程(四) ARM启动过程控制

news2024/10/2 14:31:32

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

一、实验目的

(1) 掌握建立基本完整的ARM 工程,包含启动代码,C语言程序等;

(2) 了解ARM启动过程,学会编写简单的C 语言程序和汇编启动代码并进行调试;

(3) 掌握如何指定代码入口地址与入口点;

(4) 掌握通过memory/register/watch/variable 窗口分析判断结果。

二、实验环境

硬件:PC机。

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

三、实验内容

使用汇编语言编写初始化程序,并引导至C语言main函数,用汇编语言编写延时函数实现毫秒级的延时,在C语言中调用延时函数,实现1s钟定时。

四、实验要求

(1) 在ADS下创建一个工程armasmc,编写3个文件,如下图所示:

其中一个初始化汇编语言文件Init.s,该文件中主要完成异常矢量表的建立,模式堆栈初始化,并将程序引导至C语言的main函数。

C语言程序保存为armasmc.c。 C语言中调用汇编语言文件delay.s中的毫秒延时程序delayxms,C语言将延时的毫秒数通过参数传递到汇编语言,汇编语言完成延时,然后返回C语言函数。

通过AXD运用单步执行方式调试程序。观察程序执行过程中的寄存器及存储器的变化情况。

(2)实验过程中请记录并思考以下内容:

1)如何建立异常矢量入口表?

2)如何在汇编语言中切换至C语言的main函数?。

3)如何在C语言中调用汇编语言函数,并完成参数传递?

4)汇编语言函数中用到的寄存器如何保护与恢复,为什么要保护参考程序中的R11?

5)将delay.s中的R11改成R4,并将两条R11 的保护与恢复语句stmfd sp!,{r11} 和ldmfd sp!,{r11}删掉,在C语言程序中的语句i–处设置端点,观察运行过程中变量i的变化情况,并解释其中的原因。

五、实验情况:

1、实验源代码(含注释):

Init.s代码:

;************************ entry.s ****************************
 IMPORT Main  ;在汇编程序调用该c程序前要在汇编语言程序中使用IMPORT伪操作来声明该c程序

  area Init,code,readonly   ;定义CODE片段Init 只读 
  entry     ;设置程序入口伪指令
  code32   ;以下为32位的ARM程序
; *********** Setup interrupt/exception vector *******************
start              b Reset_Handler        ;异常矢量表,根据异常矢量表进入不同模式的中断程序      
Undefined_Handler  b Undefined_Handler
SWI_Handler        b SWI_Handler
Prefetch_handler   b Prefetch_handler
Abort_Handler      b Abort_Handler
                   nop   ;Reserved vector
IRQ_Handler        b IRQ_Handler
FIQ_Handler        b FIQ_Handler

Reset_Handler     ;Reset中断,为整个中断的实际入口点        
             bl initstack    ;初始化各模式下的堆栈指针
                             
             ;切换至用户模式堆    
             msr cpsr_c,#0xd0    ;110  10000
                 
             bl Main

halt  b halt

initstack    mov r0,lr   ;r0<--lr,因为各种模式下r0是相同的而各个模式?                            
                                   
             ;设置管理模式堆栈
             msr cpsr_c,#0xd3    ;110  10011  
             ldr sp,stacksvc
               
             ;设置中断模式堆栈
             msr cpsr_c,#0xd2    ;110  10010
             ldr sp,stackirq  
             
             ;设置快速中断模式堆栈
             msr cpsr_c,#0xd1    ;110  10001
             ldr sp,stackfiq
                                
             ;设置中止模式堆栈      
             msr cpsr_c,#0xd7    ;110  10111
             ldr sp,stackabt
                                    
            ;设置未定义模式堆栈   
             msr cpsr_c,#0xdb    ;110  11011
             ldr sp,stackund
   
             ;设置系统模式堆栈    
             msr cpsr_c,#0xdf    ;110  11111
             ldr sp,stackusr
             
             mov pc,r0 ;返回
         
  LTORG      

stackusr     dcd  usrstackspace+128
stacksvc     dcd  svcstackspace+128
stackirq     dcd  irqstackspace+128
stackfiq     dcd  fiqstackspace+128
stackabt     dcd  abtstackspace+128
stackund     dcd  undstackspace+128

  area Interrupt,data,READWRITE  ;分配堆栈空间
usrstackspace space 128
svcstackspace space 128
irqstackspace space 128
fiqstackspace space 128
abtstackspace space 128
undstackspace space 128
     
       end

delay.s代码:

;************************* delay.s *****************************
  EXPORT delayxms ;EXPORT伪指令用于在程序中声明一个全局的标号,该标号可在其他的文件中引用
  area delay,code,readonly  ;定义code片段delay只读
  code32  ;以下为32位的ARM程序
  
;下面是延时若干ms的子程序      
delayxms
     stmfd sp!,{r11} ; 寄存器入栈
     sub r0,r0,#1 ;r0=r0-1
     ldr r11,=1000 ;加载至r11中
loop2
     sub r11,r11,#1 ;每次将r11自减一
     cmp r11,#0x0 ;将r11与0比较
     bne loop2  ;比较的结果不为0,则继续调用loop2  
     cmp r0,#0x0    ;将r0与0比较
     bne delayxms   ;比较的结果不为0,则继续调用delayxms
     ldmfd sp!,{r11};
     mov pc,lr;返回
     
     end

armasmc.c代码:

//*************************armasmc.c******************************
#include <stdio.h>
int Main()
{  
  extern void delayxms(int xms);  //在C程序调用汇编程序之前需要在C语言程序中使用extern关键词来声明该汇编程序
  
  int i=100;
  
  while(1)
  {
     delayxms(1000); // 调用delayxms汇编程序
     i--;
     if(i==0)
       i=100;
  }
  return 0;
}

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

1.如何建立异常矢量入口表?

答:建立异常矢量入口表需要设置中断类型号,并且要设置中断服务子程序段地址,以根据异常矢量表进入不同模式的中断程序。在实验程序中也有定义:

2.如何在汇编语言中切换至C语言的main函数?

答:由上代码可知,为保证程序调用时参数的正确传递,汇编程序设计要遵守ATPCS(ARM-Thumb Produce Call Standard),它是ARM程序和Thumb程序中子程序调用的基本规则,目的是为了使单独编译的C语言程序和汇编程序之间能够相互调用。这些基本规则包括子程序调用过程中寄存器的使用规则、数据栈的使用规则和参数的传递规则。在C程序中不需要任何关键字来声明将被汇编语言调用的C程序,但需要在汇编语言程序之前使用IMPORT伪操作来声明该C程序。在汇编程序中通过BL指令来调用子程序。同时,汇编程序可以通过地址间接访问在C语言程序中声明的全局变量。通过使用IMPORT关键词引入全局变量,并利用LDR和STR指令根据全局变量的地址可以访问它们。

3.如何在C语言中调用汇编语言函数,并完成参数传递?

答:为了保证程序调用时参数的正确传递,汇编程序设计要遵守ATPCS。在汇编程序中需要使用EXPORT伪操作来声明,同时,在C程序中调用该汇编程序之前需要在C语言程序中使用extern关键词来声明该汇编程序。

4.汇编语言函数中用到的寄存器如何保护与恢复,为什么要保护参考程序中的R11?

答:汇编语言函数中用到的寄存器通过压栈来保护,出栈来恢复。根据ATPCS规则,R11对应ARM 状态局部变量寄存器8,R11中含有循环次数的重要参量,因此要保护R11避免在程序运行与调用过程中受到影响而导致程序异常。

5.将delay.s中的R11改成R4,并将两条R11 的保护与恢复语句stmfd sp!,{r11} 和ldmfd sp!,{r11}删掉,在C语言程序中的语句i–处设置端点,观察运行过程中变量i的变化情况,并解释其中的原因。

修改程序如下:

答:由上可知R4对应局部变量寄存器1,即变量i,因此在子程序delay.s中,R4的值减为0,若不进行保护,则返回C程序后自减-1,导致变量i的值变为-1,此时将无法满足0的条件,也就无法执行if,导致i会一直递减下去,最终无法停止。

六、总结

本次有关汇编与C语言相互调用的部分,建立异常矢量入口表的方法,即需要设置中断类型号,并且要设置中断服务子程序段地址,以根据异常矢量表进入不同模式的中断程序。此外,还有ARM程序和Thumb程序中子程序调用的基本规则ATPCS(ARM-Thumb Produce Call Standard),目的是为了使单独编译的C语言程序和汇编程序之间能够相互调用。这些基本规则包括子程序调用过程中寄存器的使用规则、数据栈的使用规则和参数的传递规则,为调用提供了相关的规范。其中汇编程序访问全局C变量的方法是:汇编程序可以通过地址间接访问在C语言程序中声明的全局变量。通过使用IMPORT关键词引入全局变量,并利用LDR和STR指令根据全局变量的地址可以访问它们。在C语言程序中调用汇编程序的方法是:在汇编程序中需要使用EXPORT伪操作来声明,使得本程序可以被其它程序调用。同时,在C程序调用该汇编程序之前需要在C语言程序中使用extern关键词来声明该汇编程序。而在汇编程序中调用C语言程序的方法是:在C程序中不需要使用任何关键字来声明将被汇编语言调用的C程序,但是在汇编程序调用该C程序之前需要在汇编语言程序中使用IMPORT伪操作来声明该C程序。在汇编程序中通过BL指令来调用子程序。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/352533.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何选择好的IB课程学校?

在上海除了拼中考&#xff0c;你还可以走一条更有“选择权”的路——国际化学校&#xff01; 然而选择学校时&#xff0c;让家长最头痛的事情&#xff0c;莫过于为孩子选择什么样的国际化课程。 今天我们来聊聊IB课程&#xff01; 三大主流国际课程中&#xff0c;被公认含金量最…

操作系统引论

操作系统是管理硬件和软件的一种应用程序。操作系统是运行在计算机上最重要的一种软件&#xff0c;它管理计算机的资源和进程以及所有的硬件和软件。它为计算机硬件和软件提供了一种中间层&#xff0c;使应用软件和硬件进行分离&#xff0c;让我们无需关注硬件的实现&#xff0…

嵌入式C语言设计模式 --- 外观模式

1 - 什么是外观模式? 外观模式(Facade Pattern),是一种比较简单的结构型模式,它存在的目的,也是为了简单。 外观模式隐藏了一系列接口的复杂性,旨在为外部客户端提供一个更高层次且统一简单的接口,简化了客户端调用某些模块的一系列操作。 外观模式应该是软件工程师…

Git入门使用详细笔记小白教程

Git入门使用详细笔记小白教程 一、克隆远程仓库到本地 1.复制远程仓库的地址到URL中&#xff1a; 二、本地和远程冲突 注意事项&#xff1a; 一定要在第二次修改提交到本地之前先pull远程的项目&#xff01;&#xff01;&#xff01;不然就会本地和远程的项目起冲突。 冲突…

Selection bias mitigation in recommender system using uninteresting items学习笔记

0 简介 论文题目&#xff1a;Selection bias mitigation in recommender system using uninteresting items based on temporal visibility 发表情况&#xff1a;2023年&#xff0c;Expert Systems With Applications 论文地址&#xff1a;https://doi.org/10.1016/j.eswa.202…

Java_Maven:5. 把第三方 jar 包放入本地仓库或私服

目录 1 导入本地库 2 导入私服 3 参数说明 1 导入本地库 随便找一个 jar 包测试&#xff0c;可以先 CMD进入到 jar 包所在位置&#xff0c;运行 mvn install:install-file -DgroupIdcom.alibaba -DartifactIdfastjson -Dversion1.1.37-Dfile fastjson-1.1.37.jar -Dpackaging…

基于matlab使用深度学习的SAR目标分类

一、前言此示例演示如何创建和训练一个简单的卷积神经网络&#xff0c;以使用深度学习对 SAR 目标进行分类。深度学习是一种强大的技术&#xff0c;可用于训练健壮的分类器。它已经在从图像分析到自然语言处理的不同领域显示出其有效性。这些发展对SAR数据分析和SAR技术具有巨大…

YOLOv5简介

YOLOv5 一、输入端 1. Mosaic数据增强&#xff1a; CutMix 数据增强&#xff1a;随机生成一个裁剪框Box&#xff0c;裁剪掉A图中的相应位置&#xff0c;然后用B图相应位置的ROI放到A中被裁剪的区域中形成新的样本。采用加权求和的方式计算损失&#xff0c;将A区域中被cut掉的…

Kubernetes安全

Kubernetes RBAC授权 Kubernetes 安全框架 K8S安全控制框架主要由下面3个阶段进行控制&#xff0c;每一个阶段都支持插件方式&#xff0c;通过API Server配置来启用插件。1. Authentication&#xff08;鉴权&#xff09; K8s Apiserver提供三种客户端身份认证&#xff1a;• H…

JVM08执行引擎

执行引擎属于JVM的下层 执行引擎是Java虚拟机核心的组成部分之一。“虚拟机”是一个相对于“物理机”的概念&#xff0c;这两种机器都有代码执行能力&#xff0c;其区别是物理机的执行引擎是直接建立在处理器、缓存、指令集和操作系统层面上的&#xff0c;而虚拟机的执行引擎则…

JavaWeb5-线程常用属性

目录 1.ID 2.名称 3.状态 4.优先级 5.是否守护线程 5.1.线程类型&#xff1a; ①用户线程&#xff08;main线程默认是用户线程&#xff09; ②守护线程&#xff08;后台/系统线程&#xff09; 5.2.守护线程作用 5.3.守护线程应用 5.4.守护线程使用 ①在用户线程&am…

基础篇(-1)-java特点、JDK、JRE、JVM区别、字节码编译、跨平台、程序运行

文章目录1.Java的特点有哪些&#xff1f;2.JDK和JRE和JVM的区别3.Java为什么采用字节码编译&#xff1f;4.什么是跨平台&#xff1f;5.Java程序从源代码到运行需要三步&#xff1f;1.Java的特点有哪些&#xff1f; Java是一种编程语言&#xff0c;被特意设计用于互联网的分布式…

windwos安装spring-cloud-alibaba-nacos

windwos安装spring-cloud-alibaba-nacos前言一、预备环境二、下载源码或者安装包1.启动2.关闭总结前言 这个快速开始手册是帮忙您快速在您的电脑上&#xff0c;下载、安装并使用 Nacos。 一、预备环境 Nacos 依赖 Java 环境来运行。如果您是从代码开始构建并运行Nacos&#x…

[ vulhub漏洞复现篇 ] Drupal Core 8 PECL YAML 反序列化任意代码执行漏洞(CVE-2017-6920)

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…

Django框架进阶版

一、Django介绍 1.起源 2005年发布&#xff0c;采用python语言编写的。 早期Django主要做新闻和内容管理 重量级python web框架&#xff0c;配备了大量组件 2.组件 包含组件如下 基本配置文件/路由系统 MTV设计模式 Cookies和Session 分页和发邮件 Admin管理后台 3…

2023美赛A题完整数据!思路代码数据数学建模

选取内蒙古河套灌区&#xff08;典型干旱区&#xff09;2010-2020年气温&#xff0c;降雨&#xff0c;蒸散发和水汽压月数据 包括四种主要作物及其占比 内容截图如下&#xff1a; 链接为&#xff1a;https://www.jdmm.cc/file/2708703 同时还提供参考代码和参考文章的选项~…

格式化字符串

组包&#xff1a;按照需要的格式组成字符串解包&#xff1a;解析特定格式的数据网络信息传输解析字符串的格式使用较多&#xff01;1、sprintf用于组包将零散的数据格式按照固定的格式组成字符串#include <stdio.h> int sprintf(char *str, const char *format, ...); …

博客排名的影响是什么? 说明优点、注册方法和推荐网站

如果您经营博客&#xff0c;您是否在博客排名网站上注册&#xff1f;博客排名网站是以排名格式介绍各种注册博客的网站。如果您注册博客&#xff0c;您将有更多机会被人们看到&#xff0c;并且可以期望增加访问权限。对于那些刚刚打开博客并担心访问量不会轻易增加的人来说&…

王道考研——计算机网络(第一章 计算机网络体系结构)

1.0认识计算机网络 在下载电影&#xff08;不会出现乱序问题&#xff09;和微信收发消息&#xff08;比如表情包乱序了&#xff09;所使用的协议是不同的 1.1-1概念和功能 &#xff08;1&#xff09;计算机网络的概念 &#xff08;2&#xff09;计算机网络的功能 &#xff08;…

酸回收树脂的应用

酸洗废水 在轧钢、金属表面处理、电子元件制造等过程中需要清除钢材表面氧化铁皮而使用酸进行酸洗&#xff0c;酸洗过程中会产生废酸液和酸洗废水。 这些废酸产量大、酸度高&#xff0c;而且由于酸洗废水来自钢铁和金属表面处理的清洗水&#xff0c;水中含有多种重金属离子&am…