嵌入式系统复习--基于ARM的嵌入式程序设计

news2024/11/17 14:34:28

文章目录

  • 上一篇
  • 编译环境
    • ADS编译环境下的伪操作
    • GNU编译环境下的伪操作
    • ARM汇编语言的伪指令
  • 汇编语言程序设计
    • 相关运算操作符
    • 汇编语言格式
    • 汇编语言程序重点
    • C语言的一些技巧
  • 下一篇

上一篇

嵌入式系统复习–Thumb指令集

编译环境

ADS/SDT IDE开发环境:它由ARM公司开发,使用了CodeWarrior公司的编译器

一般的:集成了GNU开发工具的IDE开发环境:它由GNU的汇编器as、交叉编译器gcc、和链接器ld等组成

  • 伪操作:ARM汇编语言程序里的特殊指令助记符,主要作用是完成汇编程序各种准备工作,在源程序进行编译时由汇编程序处理,而不是在计算机运行期间执行
  • 宏指令:是一段独立的代码、可插在源程序中,它通过伪操作来定义。通过实际指令替代宏体实现相关的一段代码
  • 伪指令:ARM汇编语言里的特殊指令助记符,不在处理器运行期间由机器执行。它们在编译时将被合适的机器指令替代

ADS编译环境下的伪操作

常用伪操作可分为:

  • 符号定义伪操作
    1. 定义全局变量

      伪操作语法格式作用
      GBLAGBLA Variable声明一个全局的算术变量,初始化为0
      GBLLGBLL Variable声明一个全局的逻辑变量,初始化为false
      GBLSGBLS Variable声明一个全局字符串变量,初始化为空串
    2. 定义局部变量

      伪操作语法格式作用
      LCLALCLA Variable声明一个局部的算术变量,初始化为0
      LCLLLCLL Variable声明一个局部的逻辑变量,初始化为false
      LCLSLCLS Variable声明一个局部字符串变量,初始化为空串
    3. 为变量赋值

      伪操作语法格式作用
      SETAVariable SETA expr给一个算术变量赋值
      SETLVariable SETL expr给一个逻辑变量赋值
      SETSVariable SETS expr给一个字符串赋值
    4. 给一串寄存器命名

      伪操作语法格式作用
      RLISTname RLIST {list of registers}为一个通用寄存器列表定义名称
  • 数据定义伪操作
    1. 为一个变量分配内存地址
      伪操作语法格式作用
      DCB{label} DCB expr分配一段字节的内存单元,用字节的方式放expr
      DCD{label} DCD expr分配一段的内存单元,用字的方式放expr
    2. 定义数据块的起始地址
      伪操作语法格式作用
      LTORGLTORG声明一个数据缓冲池的开始(说明此指令后面不是代码,而是数据了)
  • 汇编控制伪操作
    1. 条件
      IF 逻辑表达式
      {
      ELSE	
      }
      ENDIF
      
    2. 循环
      WHILE 逻辑表达式
      ...
      WEND
      
    3. 宏定义
      类似子程序调用,但是他不是跳转到子程序,而是直接将宏定义的代码,直接复制到宏名称那里
      MACRO
      {$label} macroname {$parameter}
      MEND
      
  • 信息报告伪操作
    在程序运行不同阶段可以设置让他弹出信息
    |伪操作 | 语法格式 |作用
    |–|–|--
    |OPT| OPT n | 通过OPT可以在源程序中设置列表选项
  • 其他伪操作
    1. 告诉编译器要选择的指令
      伪操作语法格式作用
      CODE 16CODE 16告诉编译器后面是Thumb指令
      CODE 32CODE 32告诉编译器后面是ARM指令
    2. 定义常量(给变量或标号赋值)
      伪操作语法格式作用
      EQUname EQU expr将name赋值为expr
    3. 程序结构指令
      伪操作语法格式作用
      AREAAREA sectioname {, attr}定义一个代码段或数据段
      ENTRYENTRY指定程序的入口点
      ENDEND告诉编译器已经到了源程序结尾
    4. 混合调用用到的指令
      伪操作语法格式作用
      EXPORT/GLOBALEXPORT symbol {[WEAK]}声明一个文件可以被其他文件引用,相当于声明以个全局变量
      IMPORT/EXTERNIMPORT/EXTERN symbol {[WEAK]}告诉编译器当前符号不是在本源文件中定义的,而是在其他文件中,而在本文件中可能使用

GNU编译环境下的伪操作

常用伪操作为:

  • 常量编译控制伪操作

    伪操作语法格式作用
    .byte.byte expr分配一段字节空间,并用字节的方式放入expr
    .hword/ .short.hword expr分配一段半字节空间,并用半字的方式放入expr
    .ascii.ascii expr定义字符串expr(非零结束符)
    .asciz/.string.asciz定义字符串(以 /0 为结束符)
    .word.word expr分配一段字内存空间
  • 汇编程序代码控制伪操作

    伪操作语法格式作用
    .section.section expr定义域中包含的段
    .text.text{subsection}代码
    .data.data {subsection}数据
    .code 16.code 16表明后面是Thumb指令集
    .code 32.code 32表明后面是ARM指令集
    .end.end结束标识符
    .include.include “filename”将一个源文件包含到当前源文件中
  • 宏及条件编译控制伪操作

    .macro以及.endm

    .macro condition
    .endm
    

    .ifdef, .else及.endif

    .ifdef condition
    .else
    .endif
    
  • 其他伪操作

    伪操作语法格式作用
    .print.print string打印信息到标准输出

ARM汇编语言的伪指令

伪操作语法格式作用
ADRADR {cond} register, expr将基于PC或基址寄存器的地址读到寄存器中,小范围的地址读取
ADRLADRL {cond} register,expr将基于PC或基址寄存器的地址读到寄存器中,中等范围的地址读取
LDRLDR {cond} register将一个32位的立即数或一个地址值读取到寄存器中,大范围地址读取
NOPNOP汇编是替换成ARM的空指令(占用一个操作时间但什么到不做)

汇编语言程序设计

  1. 文件格式
    ARM源程序文件可以有任意一种纯文本文件编写程序代码
    文件格式对应与

    源程序文件文件名说明
    汇编程序文件*.S用ARM汇编语言编写的ARM程序或Thumb程序
    C程序文件*.C用C语言编写的程序代码
    头文件*.H通常将常量命名、宏定义、数据结构定义等放在头文件中
  2. ARM汇编语言语句格式如下:

    {符号} {指令 | 伪操作 | 伪指令} {; 注释}
    

    ;为注释符

    • 符号可以代表地址、变量和数字常量
      命名规则:符号由大小写字母、数字以及下划线组成(区分大小写)
      局部标号以数字开头,其他符号都不能以数字开头

    • 变量: 三种变量:数字变量、逻辑变量、串变量

    • 数字常量:表示方式:十进制,十六进制,n进制

    • 标号:表示程序中的指令或地址的标号,分为基于PC的标号、基于寄存器的标号、绝对地址

    • 局部标号:相对当前位置

      % {F|B} {A|T} N{routname}
      

      其中:%表示引用操作、F表示只先向前搜索、B表示向后搜索、A表示编译器搜索宏的搜索嵌套层次、T表示宏的当前层次

相关运算操作符

  1. 字符串表达式相关操作符
    • LEN:返回字符串的长度
      例:

      GBLS STR
      STR SETS "AAA"
      :LEN: STR    ;LEN = 3
      
    • CHR: 返回一个字符的ASCII值

      :CHR:A
      
    • STR: 将对应变量(数字量或逻辑量)的表示形式用字符串的形式表示
      例:

      GLBA A1
      SETA A1 15
      :STR: A1
      
    • LEFT :返回一个字符从最左端的一定长度的字串
      格式:

      A :LEFT: B
      

      A为源字符串;B为数字量,表示返回字符个数
      例:

      GBLS STR1
      GBLS STR2
      SETS STR1 "AAAABBBB"
      SETS STR2 STR1 :LEFT:3 ;结果为STR2为 “AAA”
      

      RIGHT同理,返回最右端一定长度的字串

    • CC:连接2个字符串

      A :CC: B
      

      A为第一个源字符串;B为第二个源字符串
      例:

      GBLS STR1
      GBLS STR2
      STR1 SETS "AAACCC"
      STR2 SETS "BBB" :CC: (STR1 :LEFT: 3) ; 结果为STR2 为"BBBAAA"
      
  2. 数字表达式相关操作符
    • NOT:按位取反
      :NOT: A
      
    • +、-、x、/及MOD: 算术操作符
      A + B ; 
      A - B;
      A x B;
      A / B;
      A :MOD: B;
      
    • ROL、ROR、SHL、SHR:循环移位操作
      A :ROL: B ;将整数A循环左移B位
      A :ROR: B;将整数A循环右移B位
      A :SHL: B ;将整数A左移B位空位补0
      A :SHR: B;将整数A右移B位空位补0
      
    • AND、OR、EOR:按位逻辑操作符
      A :AND: B ;按位与操作 
      A :OR: B;按位或操作
      A :EOR: B;按位异或操作
      
  3. 逻辑表达式
    • 关系操作符
      =、>、<、
      不等于 /= 或则 <>
    • 逻辑操作符
      :LNOT: ;A 取反
      A :LAND: B;逻辑与
      A :LOR: B;逻辑或
      A :LEOR: B;逻辑异或
      

汇编语言格式

ARM汇编语言是以段(section)为单位来组织源文件的。
段是相对独立的、具有特定名称的、不可分割的指令或者数据序列。
段又可以分为代码段和数据段。一个源程序至少需要一个代码段。

例:

AREA EXAMPLE(段的名字), CODE(代码段), READONLY(只读)
ENTRY(程序入口点)
start
...
END

汇编语言程序重点

  1. 子程序的调用
    子程序的调用通过BL指令来完成
    语法格式为

    BL subname(被调用子程序的名称)
    
  2. 子程序的返回
    在返回调用子程序时,将LR寄存器(R14)中的值拷贝回程序寄存器(R15)
    当没有嵌套时

    SUB2 ...
    	MOV PC, R14
    

    当发生嵌套时, 对于在子程序中出现嵌套调用时,链接寄存器LR中的返回地址可能会在第二次调用时被覆盖,所以需要将返回地址压入堆栈来进行保存

    SUB1 STMFD SP!, {R0 - R7, R14}; 保存工作寄存器和链接
    BL SUB2
    ...
    LDMFD SP!, {R0 - R7, PC}; 恢复工作寄存器并返回 
    
  3. 跳转表
    类似于c++中的switch
    调用一系列子程序中的一个,而决定调用哪一个由程序的计算值决定。
    例:

    BL JUMPTAB; R0存放对应的跳转信息 0表示0号程序...
    
    JUMPTAB ADR R1, SUBTAB; R1 <- SUBTAB
    		CMP R0, #SUBMAX; 检查是否超限
    		LDRLS PC, [R1, R0, LSL #2]; 如果OK则跳转到表中
    		B ERROR; 否则发生错误
    		
    SUBTAB DCD SUB0
    	   DCD SUB1
    	   DCD SUB2
    	   ...
    SUB MAX;散转表结束地址
    
  4. ARM与Thumb间的状态转换
    状态切换是通过一条专用的转移交换指令BX来实现的。
    当Rn寄存器中的目的地址的最后一位为0时转换到ARM状态
    当Rn寄存器中最后一位为1时,转换到Thumb状态
    Thumb地址是半字对齐的末尾一定是0

    CODE32
    	ADR R0, Into_Thumb + 1
    	BX R0
    	...
    CODE16
    	Into_Thumb:
    	...
    	ADR R5, BACK_TO_ARM
    	BX R5
    	...
    CODE32
    	Back_to_ARM
    	...
    

应用实例:

  1. 简单的ARM指令程序
    在这里插入图片描述
  2. 数据块复制
    在这里插入图片描述
  3. 利用跳转表实现程序跳转
    在这里插入图片描述

C语言的一些技巧

  1. 变量定义

    • 把所有相同类型的变量放在一起定义,这样可以优化存储器空间
    • 局部变量使用32位int或unsinged int有时会更有效率。因为每个寄存器是32位的
    • 变量定义为了精简是要避免使用冗余变量。但有时使用冗余变量可以减少存储器的访问次数,提高系统性能,冗余变量一般在寄存器,一般变量在存储器
  2. 参数传递
    为了单独编译C语言程序和汇编程序能够相互调用,定义了同一的函数过程调用标准ATPCS
    ATPCS规则:

    • 寄存器的使用规则
      子程序通过寄存器R0 ~ R3来传递参数, 使用R4 ~ R11来保存局部变量,因此在进入子程序前要保存这些寄存器的值,返回后恢复,在Thumb中,只使用R4 ~ R7
    • 数据栈的使用规则
      ATPCS规定数据栈为FD(满递减)类型,并且对数据栈的操作时8字节对齐的
    • 参数的传递规则
      当参数固定的情况下,通过寄存器R0 ~ R3来传递。其他参数通过数据栈传递
      当参数个数可变的子程序:当不超过4个时用R0 ~ R3 来传递,超过4个时,使用数据栈来传递参数
      结果返回是以32位为界,每多一个32就从R0 ~ R3中多增加一个来传递
  3. 循环时使用i -- 可以省一些汇编指令,更有效率

下一篇

未完待续

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

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

相关文章

毛虫目标检测数据集VOC格式550张

毛虫&#xff0c;一种令人惊叹的生物&#xff0c;以其独特的外貌和习性&#xff0c;成为了自然界中的一道亮丽风景。 毛虫的外观非常特别&#xff0c;身体呈圆柱形&#xff0c;表面覆盖着许多细小的毛发&#xff0c;这使得它们在叶子上伪装得非常好。它们的头部有一对坚硬的颚…

vmware安装centos 7.6 操作系统

vmware安装centos 7.6 操作系统 1、下载centos 7.6 操作系统镜像文件2、安装centos 7.6操作系统3、配置centos 7.6 操作系统3.1、配置静态IP地址 和 dns3.2、查看磁盘分区3.3、查看系统版本 1、下载centos 7.6 操作系统镜像文件 这里选择 2018年10月发布的 7.6 版本 官方下载链…

flutter学习-day23-使用extended_image处理图片的加载和操作

文章目录 1. 介绍2. 属性介绍3. 使用 1. 介绍 在 Flutter 的开发过程中&#xff0c;经常会遇到图片的显示和加载处理&#xff0c;通常显示一个图片&#xff0c;都有很多细节需要处理&#xff0c;比如图片的加载、缓存、错误处理、图片的压缩、图片的格式转换等&#xff0c;如果…

代码随想录 718. 最长重复子数组

题目 给两个整数数组 nums1 和 nums2 &#xff0c;返回 两个数组中 公共的 、长度最长的子数组的长度 。 示例 1&#xff1a; 输入&#xff1a;nums1 [1,2,3,2,1], nums2 [3,2,1,4,7] 输出&#xff1a;3 解释&#xff1a;长度最长的公共子数组是 [3,2,1] 。 示例 2&#xff1…

创新性文生视频模型,南洋理工开源FreeInit

文本领域的ChatGPT&#xff0c;画图领域的Midjourney都展现出了大模型强大的一面&#xff0c;虽然视频领域有Gen-2这样的领导者&#xff0c;但现有的视频扩散模型在生成的效果中仍然存在时间一致性不足和不自然的动态效果。 南洋理工大学S实验室的研究人员发现&#xff0c;扩散…

前端 -- 基础 路径 -- 相对路径 详解

目录 导语引入 &#xff1a; 相对路径 &#xff1a; 相对路径 包含哪些 &#xff1a; 同一级路径 &#xff1a; 下一级路径 &#xff1a; 上一级路径 &#xff1a; 导语引入 &#xff1a; # 大家都清楚&#xff0c;在我们日常所见到的网页里&#xff0c;要涉及好多…

imgaug库指南(五):从入门到精通的【图像增强】之旅

引言 在深度学习和计算机视觉的世界里&#xff0c;数据是模型训练的基石&#xff0c;其质量与数量直接影响着模型的性能。然而&#xff0c;获取大量高质量的标注数据往往需要耗费大量的时间和资源。正因如此&#xff0c;数据增强技术应运而生&#xff0c;成为了解决这一问题的…

微信小程序如何搜索iBeacon设备

1.首先在utils文件夹下创建bluetooth.js和ibeacon.js 2.在 bluetooth.js文件中写入 module.exports {initBluetooth: function () {// 初始化蓝牙模块wx.openBluetoothAdapter({success: function (res) {console.log(蓝牙模块初始化成功);},fail: function (res) {console.l…

C++ 释放指针

在C中&#xff0c;释放指针通常使用delete或delete[]操作符&#xff1b; 如果指针指向的是单个对象&#xff0c;可以使用delete操作符进行释放&#xff1b; 在释放完内存后&#xff0c;最好将指针置为nullptr&#xff0c;以避免出现悬空指针&#xff08;dangling pointer&#…

【大数据】Zookeeper 集群及其选举机制

Zookeeper 集群及其选举机制 1.安装 Zookeeper 集群2.如何选取 Leader 1.安装 Zookeeper 集群 我们之前说了&#xff0c;Zookeeper 集群是由一个领导者&#xff08;Leader&#xff09;和多个追随者&#xff08;Follower&#xff09;组成&#xff0c;但这个领导者是怎么选出来的…

wpsjs学习——获取单元格批注

1.获取第一个单元格的值&#xff1a; wps.Application.ActiveSheet.Range(A1).Value2; 2.1.获取第一个单元格的批注&#xff1a; wps.Application.ActiveSheet.Range(A1).Comment.Text(); <div class"global">获取表格信息<div class"divItem">…

vr眼镜和AR眼镜的区别有哪些?哪些产品可以支持VR应用?

vr眼镜怎么连接手机 要将VR眼镜连接到手机上&#xff0c;您可以按照以下步骤进行&#xff1a; 1. 确保您的手机支持VR应用程序&#xff1a;首先&#xff0c;确保您的手机具备运行VR应用程序的硬件和软件条件。一些VR应用程序可能对设备有特定的要求&#xff0c;如处理器性能、操…

x-cmd pkg | pdfcpu - 强大的 PDF 处理工具

目录 简介首次用户多功能支持性能表现安全的加密处理进一步阅读 简介 pdfcpu 是一个用 Go 编写的 PDF 处理库。同时它也提供 API 和 CLI。pdfcpu 提供了丰富的 PDF 操作功能&#xff0c;用户还能自己编写配置文件&#xff0c;用来管理和使用各种自定义字体并存储有效的默认配置…

VR与数字孪生:共同构筑未来的虚拟世界

随着科技的不断发展&#xff0c;数字孪生和VR已经成为当今热门的科技话题。作为山海鲸可视化软件的开发者&#xff0c;我们对这两者都有深入的了解。在此&#xff0c;我们将详细探讨数字孪生与VR的区别和联系。 首先&#xff0c;数字孪生&#xff08;Digital Twin&#xff09;…

洛谷——P1983 [NOIP2013 普及组] 车站分级(拓扑排序、c++)

文章目录 一、题目[NOIP2013 普及组] 车站分级题目背景题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 样例 #2样例输入 #2样例输出 #2 提示 二、题解基本思路&#xff1a;代码 一、题目 [NOIP2013 普及组] 车站分级 题目背景 NOIP2013 普及组 T4 题目描述 一条单…

美年大健康黄伟:从选型到迁移,一个月升级核心数据库

核心生产系统的数据库&#xff0c;从接到替换需求到完成分布式升级&#xff0c;需要多久&#xff1f;一个月&#xff0c;这是美年大健康的回答。一个月集中调配各种资源&#xff0c;美年大健康完成了应用程序基本零改造的平滑迁移&#xff0c;新数据库在成本更低的前提下&#…

【Android】自定义View组件,并实现在 Compose、Kotlin、Xml 中调用

从事 Android 开发以来&#xff0c;很少有过自定义 View 的相关开发需求&#xff0c;大部分 UI 都是可以集成某些官方组件&#xff0c;在组件的基础上完成能够大大缩短开发时间。但今天我要讲的是&#xff1a;如何使用 Android 开发一个Compose、Xml都可以调用的组件&#xff1…

Vue中break关键字

Change() {//每次触发该事件&#xff0c;都要讲data重新赋值一次this.data JSON.parse(JSON.stringify(this.data1));// 根据选中的等级更新数据switch (this.selectedlevel) {case 1:// 更新数据为一级数据this.data this.data.filter(item > item.level "1"…

架构(1)

目录 1.如何理解架构的演进&#xff1f; 2.如何理解架构的服务化趋势&#xff1f; 3.架构中有哪些技术点&#xff1f; 4.谈谈架构中的缓存应用&#xff1f; 5.在开发中缓存具体如何实现&#xff1f; 1.如何理解架构的演进&#xff1f; 初始阶段的网站架构应用服务和数据服…

2024年1月6日 十二生肖 今日运势

小运播报&#xff1a;2024年1月6日&#xff0c;星期六&#xff0c;农历十一月廿五 &#xff08;癸卯年乙丑月己巳日&#xff09;&#xff0c;法定节假日。 红榜生肖&#xff1a;牛、猴、鸡 需要注意&#xff1a;鼠、虎、猪 喜神方位&#xff1a;东北方 财神方位&#xff1a…