嵌入式系统复习--基于ARM的嵌入式程序设计
文章目录
- 上一篇
- 编译环境
- ADS编译环境下的伪操作
- GNU编译环境下的伪操作
- ARM汇编语言的伪指令
- 汇编语言程序设计
- 相关运算操作符
- 汇编语言格式
- 汇编语言程序重点
- C语言的一些技巧
- 下一篇
上一篇
嵌入式系统复习–Thumb指令集
编译环境
ADS/SDT IDE开发环境:它由ARM公司开发,使用了CodeWarrior公司的编译器
一般的:集成了GNU开发工具的IDE开发环境:它由GNU的汇编器as、交叉编译器gcc、和链接器ld等组成
- 伪操作:ARM汇编语言程序里的特殊指令助记符,主要作用是完成汇编程序各种准备工作,在源程序进行编译时由汇编程序处理,而不是在计算机运行期间执行
- 宏指令:是一段独立的代码、可插在源程序中,它通过伪操作来定义。通过实际指令替代宏体实现相关的一段代码
- 伪指令:ARM汇编语言里的特殊指令助记符,不在处理器运行期间由机器执行。它们在编译时将被合适的机器指令替代
ADS编译环境下的伪操作
常用伪操作可分为:
- 符号定义伪操作
-
定义全局变量
伪操作 语法格式 作用 GBLA GBLA Variable 声明一个全局的算术变量,初始化为0 GBLL GBLL Variable 声明一个全局的逻辑变量,初始化为false GBLS GBLS Variable 声明一个全局字符串变量,初始化为空串 -
定义局部变量
伪操作 语法格式 作用 LCLA LCLA Variable 声明一个局部的算术变量,初始化为0 LCLL LCLL Variable 声明一个局部的逻辑变量,初始化为false LCLS LCLS Variable 声明一个局部字符串变量,初始化为空串 -
为变量赋值
伪操作 语法格式 作用 SETA Variable SETA expr 给一个算术变量赋值 SETL Variable SETL expr 给一个逻辑变量赋值 SETS Variable SETS expr 给一个字符串赋值 -
给一串寄存器命名
伪操作 语法格式 作用 RLIST name RLIST {list of registers} 为一个通用寄存器列表定义名称
-
- 数据定义伪操作
- 为一个变量分配内存地址
伪操作 语法格式 作用 DCB {label} DCB expr 分配一段 字节
的内存单元,用字节的方式放exprDCD {label} DCD expr 分配一段 字
的内存单元,用字的方式放expr - 定义数据块的起始地址
伪操作 语法格式 作用 LTORG LTORG 声明一个数据缓冲池的开始(说明此指令后面不是代码,而是数据了)
- 为一个变量分配内存地址
- 汇编控制伪操作
- 条件
IF 逻辑表达式 { ELSE } ENDIF
- 循环
WHILE 逻辑表达式 ... WEND
- 宏定义
类似子程序调用,但是他不是跳转到子程序,而是直接将宏定义的代码,直接复制到宏名称那里MACRO {$label} macroname {$parameter} MEND
- 条件
- 信息报告伪操作
在程序运行不同阶段可以设置让他弹出信息伪操作 语法格式 作用 OPT OPT n 通过OPT可以在源程序中设置列表选项 - 其他伪操作
- 告诉编译器要选择的指令
伪操作 语法格式 作用 CODE 16 CODE 16 告诉编译器后面是Thumb指令 CODE 32 CODE 32 告诉编译器后面是ARM指令 - 定义常量(给变量或标号赋值)
伪操作 语法格式 作用 EQU name EQU expr 将name赋值为expr - 程序结构指令
伪操作 语法格式 作用 AREA AREA sectioname {, attr} 定义一个代码段或数据段 ENTRY ENTRY 指定程序的入口点 END END 告诉编译器已经到了源程序结尾 - 混合调用用到的指令
伪操作 语法格式 作用 EXPORT/GLOBAL EXPORT symbol {[WEAK]} 声明一个文件可以被其他文件引用,相当于声明以个全局变量 IMPORT/EXTERN IMPORT/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汇编语言的伪指令
伪操作 | 语法格式 | 作用 |
---|---|---|
ADR | ADR {cond} register, expr | 将基于PC或基址寄存器的地址读到寄存器中,小范围的地址读取 |
ADRL | ADRL {cond} register,expr | 将基于PC或基址寄存器的地址读到寄存器中,中等范围的地址读取 |
LDR | LDR {cond} register | 将一个32位的立即数或一个地址值读取到寄存器中,大范围地址读取 |
NOP | NOP | 汇编是替换成ARM的空指令(占用一个操作时间但什么到不做) |
汇编语言程序设计
-
文件格式
ARM源程序文件可以有任意一种纯文本
文件编写程序代码
文件格式对应与源程序文件 文件名 说明 汇编程序文件 *.S 用ARM汇编语言编写的ARM程序或Thumb程序 C程序文件 *.C 用C语言编写的程序代码 头文件 *.H 通常将常量命名、宏定义、数据结构定义等放在头文件中 -
ARM汇编语言语句格式如下:
{符号} {指令 | 伪操作 | 伪指令} {; 注释}
;为注释符
-
符号可以代表地址、变量和数字常量
命名规则:符号由大小写字母、数字以及下划线组成(区分大小写)
局部标号以数字开头,其他符号都不能以数字开头 -
变量: 三种变量:数字变量、逻辑变量、串变量
-
数字常量:表示方式:十进制,十六进制,n进制
-
标号:表示程序中的指令或地址的标号,分为基于PC的标号、基于寄存器的标号、绝对地址
-
局部标号:相对当前位置
% {F|B} {A|T} N{routname}
其中:%表示引用操作、F表示只先向前搜索、B表示向后搜索、A表示编译器搜索宏的搜索嵌套层次、T表示宏的当前层次
-
相关运算操作符
- 字符串表达式相关操作符
-
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"
-
- 数字表达式相关操作符
- 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;按位异或操作
- NOT:按位取反
- 逻辑表达式
- 关系操作符
=、>、<、
不等于 /= 或则 <> - 逻辑操作符
:LNOT: ;A 取反 A :LAND: B;逻辑与 A :LOR: B;逻辑或 A :LEOR: B;逻辑异或
- 关系操作符
汇编语言格式
ARM汇编语言是以段(section)为单位来组织源文件的。
段是相对独立的、具有特定名称的、不可分割的指令或者数据序列。
段又可以分为代码段和数据段。一个源程序至少需要一个代码段。
例:
AREA EXAMPLE(段的名字), CODE(代码段), READONLY(只读)
ENTRY(程序入口点)
start
...
END
汇编语言程序重点
-
子程序的调用
子程序的调用通过BL指令来完成
语法格式为BL subname(被调用子程序的名称)
-
子程序的返回
在返回调用子程序时,将LR寄存器(R14)中的值拷贝回程序寄存器(R15)
当没有嵌套时SUB2 ...MOV PC, R14
当发生嵌套时, 对于在子程序中出现嵌套调用时,链接寄存器LR中的返回地址可能会在第二次调用时被覆盖,所以需要将返回地址压入堆栈来进行保存
SUB1 STMFD SP!, {R0 - R7, R14}; 保存工作寄存器和链接 BL SUB2 ... LDMFD SP!, {R0 - R7, PC}; 恢复工作寄存器并返回
-
跳转表
类似于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;散转表结束地址
-
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...
应用实例:
- 简单的ARM指令程序
- 数据块复制
AREA STRINGCOPY, CODE, READ ONLY
NUM EQU 20
CODE 32
ENTRY
startLDR R0, =srcLDR R1, =dst LDR R2, #NUM; 移动字符串个数LDR SP, #0x400 ; 初始化堆栈指针
BACK; 备份STMFD SP!, {R4-R11}; 将R4与R11中的内容提前保护MOVS R3, R2, LSR #3; 移动次数NUM整除8的商BEQ YUSHU; 如果不满8个字符,看是否有余数
BLOCKCOPY ; 按块移动每次移动8个字符LDMIA R0!, {R4-R11} ;将src中8个字符块移动到R4到R11中STMIA R1!, {R4-R11} ;将移入的字符移到dst中SUBS R3, R3, #1BNE BLOCKCOPY; 未把商移动完就循环LDMFD SP!, {R4-R11}; 将保护的寄存器出栈
YUSHUANDS R2, R2, #7; 将R2只保留8以内的余数了,方便后边一个字符的搬运BEQ stop
WCOPY ; 一个字符一个字符的移动LDR R3, [R0], #4; 字对齐每次移动4STR R3, [R1], #4SUBS R2, R2, #1BNE WCOPY
stopMOV R0, #0x18LDR R1, #0x20026SWI 0x123456
AREA DATA1, DATE, READWRITE
src DCD 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4
dst DCD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
END
- 利用跳转表实现程序跳转
C语言的一些技巧
-
变量定义
- 把所有相同类型的变量放在一起定义,这样可以优化存储器空间
- 局部变量使用32位int或unsinged int有时会更有效率。因为每个寄存器是32位的
- 变量定义为了精简是要避免使用冗余变量。但有时使用冗余变量可以减少存储器的访问次数,提高系统性能,冗余变量一般在寄存器,一般变量在存储器
-
参数传递
为了单独编译C语言程序和汇编程序能够相互调用,定义了同一的函数过程调用标准ATPCS
ATPCS规则:- 寄存器的使用规则
子程序通过寄存器R0 ~ R3来传递参数, 使用R4 ~ R11来保存局部变量,因此在进入子程序前要保存这些寄存器的值,返回后恢复,在Thumb中,只使用R4 ~ R7 - 数据栈的使用规则
ATPCS规定数据栈为FD(满递减)类型,并且对数据栈的操作时8字节对齐的 - 参数的传递规则
当参数固定的情况下,第一个整数参数通过寄存器R0 ~ R3来传递。其他参数通过数据栈传递
当参数个数可变的子程序:当不超过4个时用R0 ~ R3 来传递,超过4个时,使用数据栈来传递参数
结果返回是以32位为界,每多一个32就从R0 ~ R3中多增加一个来传递
- 寄存器的使用规则
-
循环时使用
i --
可以省一些汇编指令,更有效率
下一篇
未完待续
相关文章:

嵌入式系统复习--基于ARM的嵌入式程序设计
文章目录 上一篇编译环境ADS编译环境下的伪操作GNU编译环境下的伪操作ARM汇编语言的伪指令 汇编语言程序设计相关运算操作符汇编语言格式汇编语言程序重点C语言的一些技巧 下一篇 上一篇 嵌入式系统复习–Thumb指令集 编译环境 ADS/SDT IDE开发环境:它由ARM公司开…...

【C++入门到精通】异常 | 异常的使用 | 自定义异常体系 [ C++入门 ]
阅读导航 引言一、C异常的概念二、异常的使用1. 异常的抛出和捕获(1)throw(2)try-catch(3)catch(. . .)(4)异常的抛出和匹配原则(5)在函数调用链中异常栈展开…...

NX二次开发 Block UI 指定方位控件的应用
一、概述 NX二次开发中一般都是多个控件的组合,这里我首先对指定方位控件进行说明并结合选择对象控件,具体如下图所示。 二、实现功能获取方位其在选择面上原点的目标 2.1 在initialize_cb()函数中进行初始化,实现对象选择过滤面 //过滤平…...

2024年【R2移动式压力容器充装】模拟考试及R2移动式压力容器充装实操考试视频
题库来源:安全生产模拟考试一点通公众号小程序 2024年【R2移动式压力容器充装】模拟考试及R2移动式压力容器充装实操考试视频,包含R2移动式压力容器充装模拟考试答案和解析及R2移动式压力容器充装实操考试视频练习。安全生产模拟考试一点通结合国家R2移…...
数仓工具—Hive进阶之StorageHandler(23)
Storage Handler 引入Storage Handler,Hive用户使用SQL的方式读写外部数据源, 例如ElasticSearch、 Kafka、HBase等数据源的查询对非专业开发是有一定门槛的,借助Storage Handler,他们有了一种方便快捷的手段查询数据,Storage Handler作为Hive的存储插件,我们需要的时候直…...
科技创新创业
科技创新创业是一个涉及多个方面的过程,主要包括以下几个方面: 创意产生:创业的起始点通常是一个新的创意或想法,这可能是一个新的产品、服务或技术的概念。这个创意需要独特且具有商业潜力。市场调研:一旦有了创意&a…...

高校电力能耗监测精细化管理系统,提升能源利用效率的利器
电力是高校不可离开的重要能源,为学校相关管理人员提供在线用能查询统计等服务。通过对学校照明用电、空调用电等数据的采集、监控、分析,为学校电能管理制定合理的能源政策提供参考。同时,也可以培养学生的节能意识,学校后勤电力…...

Java_Swing程序设计
swing组件允许编程人员在跨平台时指定统一的外观和风格。 Swing组件通常被称为轻量级组件, JFrame在程序中的语法格式: JFrame jfnew JFrame(title); Container containerjf.getContentPane(); jf:JFrame类的对象 container:Container类的对象。 J…...

ZeroBind:DTI零样本预测器
现有的药物-靶点相互作用(DTI)预测方法通常无法很好地推广到新的(unseen)蛋白质和药物。 在这项研究中,作者提出了一种具有子图匹配功能的蛋白质特异性元学习框架 ZeroBind,用于根据其结构预测蛋白质-药物相…...

Win10子系统Ubuntu实战(一)
在 Windows 10 中安装 Ubuntu 子系统(Windows Subsystem for Linux,简称 WSL)有几个主要的用途和好处:Linux 环境的支持、跨平台开发、命令行工具、测试和验证、教育用途。总体而言,WSL 提供了一种将 Windows 和 Linux…...
[足式机器人]Part3 机构运动学与动力学分析与建模 Ch00-2(3) 质量刚体的在坐标系下运动
本文仅供学习使用,总结很多本现有讲述运动学或动力学书籍后的总结,从矢量的角度进行分析,方法比较传统,但更易理解,并且现有的看似抽象方法,两者本质上并无不同。 2024年底本人学位论文发表后方可摘抄 若有…...

云计算历年题整理
目录 第一大题 第一大题HA计算 给出计算连接到EC2节点的EBS的高可用性(HA)的数学公式,如场景中所述;计算EC2节点上的EBS的高可用性(HA);场景中80%的AWS EC2节点用于并行处理,总共有100个虚拟中央处理单元(vCPUs)用于处理数据&a…...
2401vim,vim重要修改更新大全
原文 2023 更好的UTF-16支持 添加strutf16len()和utf16idx(),并在byteidx(),byteidxcomp()和charidx()中添加utf16标志,在内置.txt文档中. 添加crypymethod xchacha20v2 与xchacha20基本相同,但更能抵御libsodium的变化. 2022 添加"smoothscroll" 用鼠标滚动…...
安卓多用户管理之Userinfo
目录 前言Userinfo----用户信息1.1 属性1.2 构造器1.3 信息的判断及获取方法1.3.1 获取默认用户类型1.3.2 基础信息判断 1.4 序列化部分 总结 前言 UserManagerService内部类UserData中有一个Userinfo类型的info参数,在UserData中并未有所体现,但在后续…...
JavaScript-流程控制-笔记
1.流程语句的分类 顺序结构 分支结构 循环结构 2.if语句 1)if结构 if( 条件 ){ // 条件成立执行的代码 } 2)if else 结构 if( 条件 ){ // 条件成立执行的代码 }else{ // 条件不成…...

springboot + vue3实现增删改查分页操作
springboot vue3实现增删改查分页操作 环境最终实现效果实现功能主要框架代码实现数据库后端前端 注意事项 环境 jdk17 vue3 最终实现效果 实现功能 添加用户,禁用,启用,删除,编辑,分页查询 主要框架 后端 spri…...
leetcode01-重复的子字符串
题目链接:459. 重复的子字符串 - 力扣(LeetCode) 一般思路: 如果存在k是S的字串,记k的长度为s,S的长度为n,则一定有n是s的倍数,且满足对于j∈[s,n],一定存在s[j]s[j-s]; …...

目标检测数据集 - 夜间行人检测数据集下载「包含VOC、COCO、YOLO三种格式」
数据集介绍:夜间、低光行人检测数据集,真实场景高质量图片数据,涉及场景丰富,比如夜间街景行人、夜间道路行人、夜间遮挡行人、夜间严重遮挡行人数据;适用实际项目应用:公共场所监控场景下夜间行人检测项目…...

【YOLO系列】 YOLOv4思想详解
前言 以下内容仅为个人在学习人工智能中所记录的笔记,先将目标识别算法yolo系列的整理出来分享给大家,供大家学习参考。 本文未对论文逐句逐段翻译,而是阅读全文后,总结出的YOLO V4论文的思路与实现路径。 若文中内容有误…...

查询json数组
步骤一:创建表格 首先,我们需要创建一个表格来存储包含JSON对象数组的数据。可以使用以下代码创建一个名为 my_table 的表格: CREATE TABLE my_table (id INT PRIMARY KEY AUTO_INCREMENT,json_data JSON ); 上述代码创建了一个包含两个列的…...

IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...

零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...

华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...
C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...

MySQL:分区的基本使用
目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区(Partitioning)是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分(分区)可以独立存储、管理和优化,…...

永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器
一、原理介绍 传统滑模观测器采用如下结构: 传统SMO中LPF会带来相位延迟和幅值衰减,并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF),可以去除高次谐波,并且不用相位补偿就可以获得一个误差较小的转子位…...