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

文章目录

  • 上一篇
  • 编译环境
    • 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
      
  • 信息报告伪操作
    在程序运行不同阶段可以设置让他弹出信息
    伪操作语法格式作用
    OPTOPT 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: 将对应变量(数字量或逻辑量)的表示形式用字符串的形式表示
      例:

      GBLA A1
      A1 SETA 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 <- SUBTABCMP R0, #SUBMAX; 检查是否超限LDRLS PC, [R1, R0, LSL #2]; 如果OK则跳转到表中B ERROR; 否则发生错误SUBTAB DCD SUB0DCD SUB1DCD SUB2...
    SUB MAX;散转表结束地址
    
  4. ARM与Thumb间的状态转换
    状态切换是通过一条专用的转移交换指令BX来实现的。
    当Rn寄存器中的目的地址的最后一位为0时转换到ARM状态
    当Rn寄存器中最后一位为1时,转换到Thumb状态
    Thumb地址是半字对齐的末尾一定是0

    CODE32ADR R0, Into_Thumb + 1BX R0...
    CODE16Into_Thumb:...ADR R5, BACK_TO_ARMBX R5...
    CODE32Back_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.mzph.cn/news/600946.shtml

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

相关文章

西电期末1025.平滑滤波

一.题目 二.分析与思路 别光看公式&#xff0c;读题干&#xff1a;“位置i的输出为距离i最近的三个输入的平均值”&#xff0c;再看示例&#xff0c;输入几个&#xff0c;输出几个&#xff0c;所以就是输出每个位置距离最近的三个输入的平均值&#xff0c;中间没什么问题&…

HarmonyOS 应用开发学习笔记 状态管理概述

移动端开发&#xff0c;最重要的一点就是数据的处理&#xff0c;并且正确的显示渲染UI。 变量在页面和组件、组件和组件之间有时候并不能实时共享&#xff0c;而有时候&#xff0c;又不需要太多的作用域&#xff08;节省资源&#xff09;&#xff0c;作用就需要根据不同场景&am…

11.2 Linux串口驱动框架

tty 驱动程序框架 tty 驱动程序从下往上分别是设备驱动层、行规程、终端虚拟化、TTY I/O层&#xff0c;它们的功能如下&#xff1a; 设备驱动层&#xff1a;用于驱动设备&#xff0c;如串口、显示器、键盘等。行规程&#xff1a;用于处理控制字符、回显输入数据、缓存输入数据…

如何获取unicode字符串的LPCWSTR?

今天在学习window编程方面的内容时&#xff0c;我想要修改一个窗口的标题&#xff0c;这个标题的内容是窗口的高度&#xff0c;这就遇到一个问题&#xff0c;设置标题的方法是SetWindowText&#xff0c;其第二个形参是LPCWSTR类型&#xff0c;怎么把内容显示到窗口标题栏上呢&a…

两数之和 ? 三数之和? 四数之和? 统统搞定

&#x1f388;个人主页:&#x1f388; :✨✨✨初阶牛✨✨✨ &#x1f43b;推荐专栏1: &#x1f354;&#x1f35f;&#x1f32f;C语言初阶 &#x1f43b;推荐专栏2: &#x1f354;&#x1f35f;&#x1f32f;C语言进阶 &#x1f511;个人信条: &#x1f335;知行合一 前言 声明…

useContext

可以跨组件传值 其实主要的就是三步 1、const xxx React.createContext();创建一个context 2、<xxx.Provider value{{ num, setNum }}>父组件设置要传递的值 3、const { num, setNum } React.useContext(xxx);子组件下使用 特点&#xff1a; 1、可以有多个xxx.Pr…

【数字图像处理技术与应用】2023-2024上图像处理期中-云南农业大学

一、填空题&#xff08;每空2 分&#xff0c;共 30 分&#xff09; 1、图像就是3D 场景在 二维 平面上的影像&#xff0c;根据其存储方式和表现形式&#xff0c;可以将图像分为 模拟 图像和数字图像两大类&#xff1b; 2、在用计算机对数字图像处理中&#xff0c;常用一个 二…

全国(山东、安徽)职业技能大赛--信息安全管理与评估大赛题目+答案讲解——2023年国赛模拟题-linux应急响应

🍬 博主介绍👨‍🎓 博主介绍:大家好,我是 hacker-routing ,很高兴认识大家~ ✨主攻领域:【渗透领域】【应急响应】 【python】 【VulnHub靶场复现】【面试分析】 🎉点赞➕评论➕收藏 == 养成习惯(一键三连)😋 🎉欢迎关注💗一起学习👍一起讨论⭐️一起进步…

MATLAB - MPC - 优化问题(Optimization Problem)

系列文章目录 前言 模型预测控制可在每个控制间隔内解决一个优化问题&#xff0c;具体来说就是二次规划(QP)。求解结果决定了被控对象在下一个控制间隔之前使用的操纵变量&#xff08;MV&#xff09;。 该 QP 问题具有以下特点&#xff1a; 目标或 "成本 "函数 - …

数据结构(JS实现)

目录 链表链表的特点链表中的常见操作单链表append(data)尾部追加新节点toString()输出链表的节点数据插入节点insert(position,data)get(position)获取链表指定位置节点的数据indexOf(data)查找对应数据节点的位置update(position, newData)更新指定位置节点数据removeAt(posi…

【STM32】STM32学习笔记-ADC单通道 ADC多通道(22)

00. 目录 文章目录 00. 目录01. ADC简介02. ADC相关API2.1 RCC_ADCCLKConfig2.2 ADC_RegularChannelConfig2.3 ADC_Init2.4 ADC_InitTypeDef2.5 ADC_Cmd2.6 ADC_ResetCalibration2.7 ADC_GetResetCalibrationStatus2.8 ADC_StartCalibration2.9 ADC_GetCalibrationStatus2.10 A…

197.【2023年华为OD机试真题(C卷)】执行时长(模拟题-JavaPythonC++JS实现)

🚀点击这里可直接跳转到本专栏,可查阅顶置最新的华为OD机试宝典~ 本专栏所有题目均包含优质解题思路,高质量解题代码(Java&Python&C++&JS分别实现),详细代码讲解,助你深入学习,深度掌握! 文章目录 一. 题目-执行时长二.解题思路三.题解代码Python题解代码…

前端接收后端传的文件流并下载解决乱码问题

因项目需求手写了一个导出&#xff0c;但是前端获取时出现了乱码&#xff0c;搜到一下解决方案&#xff1a; 两种情况&#xff1a; 1.如果这个接口是get的请求&#xff1a; 后端返回文件流&#xff0c;前端可能会导出txt或者excel的时候&#xff0c;里面的中文会出现乱码文章…

java 音乐会售票平台系统Myeclipse开发mysql数据库struts2结构java编程计算机网页项目

一、源码特点 java 音乐会售票平台系统 是一套完善的web设计系统&#xff0c;对理解JSP java编程开发语言有帮助struts2框架开发mvc模式&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发 环境为TOCAT7.0,Myeclipse8.5开发&#xff0c;数据…

【投稿优惠|优质会议】2024年材料化学与清洁能源国际学术会议(IACMCCE 2024)

【投稿优惠|优质会议】2024年材料化学与清洁能源国际学术会议(IACMCCE 2024) 2024 International Conference Environmental Engineering and Mechatronics Integration(ICEEMI 2024) 一、【会议简介】 随着全球能源需求的不断增长&#xff0c;清洁能源的研究与应用成为了国际…

三叠云流程制造ERP:构建智慧工厂,实现高效生产管理

在数字化经济的浪潮下&#xff0c;新一代信息技术快速发展&#xff0c;深度整合&#xff0c;引领了工业的创新和变革&#xff0c;推动了企业向智能化发展。解决生产管理、销售管理和技术管理等难题的关键&#xff0c;在于管理者能否及时准确地掌握企业运营信息。三叠云流程制造…

读书之深入理解ffmpeg_简单笔记2(初步)

再回看第一遍通读后的笔记&#xff0c;感觉还有很多的细节需要一一攻克,。 mp4的封装格式&#xff0c;解析方式。 flv的封装格式&#xff0c;解析方式。 ts的封装格式&#xff0c;解析方式。 第四章 封装和解封装 4.2 视频文件转flv &#xff08;头文件和文件内容&#xff0…

Django发送QQ邮件

创建一个表单&#xff0c;供用户填写他们的姓名和电子邮件、电子邮件收件人和可选的注释 创建blog/forms.py from django import formsclass EmailPostForm(forms.Form):name forms.CharField(max_length25)email forms.EmailField()to forms.EmailField()comments forms.…

【ARMv8架构系统安装PySide2】

ARMv8架构系统安装PySide2 Step1. 下载Qt资源包Step2. 配置和安装Qt5Step3. 检查Qt-5.15.2安装情况Step4. 安装PySide2所需的依赖库Step5. 下载和配置PySide2Step6. 检验PySide2是否安装成功 Step1. 下载Qt资源包 if you need the whole Qt5 (~900MB): wget http://master.qt…

密码学(一)

文章目录 前言一、Cryptographic Primitives二、Cryptographic Keys2.1 Symmetric key cryptography2.2 asymmetric key cryptography 三、Confidentiality3.1 Symmetric key encryption algorithms3.2 asymmetric key block ciphers3.3 其他 四、Integrity4.1 symmetric key s…