嵌入式学习札记(基于STM32L431) 一、ARM Cortex-M4微处理器

2023-05-16

ARM Cortex-M4微处理器

  • 写在前面
  • ARM Cortex-M4微处理器简介
    • ARM Cortex-M4微处理器内部结构概要
      • 位数
      • 总线结构
      • 中断控制
      • 存储器保护
      • 低功耗
      • 内部寄存器
    • 寻址方式与机器码获取方法
      • 指令保留字简表与寻址方式
        • 指令保留字简表
        • 寻址方式
          • 立即数寻址
          • 寄存器寻址
          • 直接寻址
          • 偏移寻址及寄存器间接寻址
      • 机器的指令码
        • 运行源文件
        • 执行程序所获得的信息
    • 基本指令分类解析
      • 数据传送类指令
        • 取数指令
        • 存数指令
        • 寄存器间数据传送指令
    • 汇编语言的基本语法
      • 汇编语言的格式
        • 标号
        • 操作码
        • 操作数
        • 注释
      • 常用伪指令简介
        • 系统预定义的段
        • 常量的定义
        • 程序中插入常量
        • 条件伪指令
        • 文件包含伪指令
        • 其他常用伪指令

写在前面

本系列学习主要参照了王宜怀老师主编,清华大学出版社出版的《嵌入式技术基础与实践(第六版)》一书,有兴趣的可以自行购买,正版书籍附赠开发版供实验所需

ARM Cortex-M4微处理器简介

ARM Cortex-M4微处理器内部结构概要

具体介绍请参考书籍

位数

Cortex-M4系列处理器为32位处理器,内部存储器,数据总线均为32位,采用Thumb-2技术,同时支持16位与32位指令

总线结构

采用哈佛架构(感兴趣可以自行查阅),统一的存储空间编址,32位寻址,最多支持4GB的存储空间;三级流水线设计;片上接口基于AMBA架构

中断控制

采用了集成嵌套向量中断控制器(NVIC),支持8~256个中断优先级,最多240个中断请求

存储器保护

可选的MPU

低功耗

多种低功耗特性和休眠模式

内部寄存器

M4微处理器的寄存器包含用于数据处理与控制的寄存器、特殊功能寄存器与浮点寄存器。特殊功能寄存器有预定义的功能,必须通过专用指令来访问。

寄存器类型序号
低位寄存器R0~R7
高位寄存器R8~R12
SPR13
LPR14
PCR15
PSR(程序状态寄存器)特殊功能寄存器
PRIMASK、FAULTMASK、BASEPRI(异常屏蔽寄存器)同上
CONTROL(控制寄存器)同上

寻址方式与机器码获取方法

CPU可以执行特定功能的操作命令被称为指令
CPU所能执行的各种指令的集合,成为该CPU的指令系统

指令保留字简表与寻址方式

指令保留字简表

其他指令请查阅《ARM v7-M 参考手册》

类型保留字含义
数据传送类ADR生成与PC指针相关的地址
LDR、LDRH、LDRB、LDRSB、LDRSH、LDMIA将存储器中的内容加载到寄存器中
STR、STRH、STRB、STMIA将寄存器中的内容存储到存储器中
MOV、MVN寄存器间数据传送
PUSH、POP进栈出栈
数据操作类下为子类
算数运算类ADC、ADD、SBC、SUB、MUL加、减、乘指令
CMN、CMP比较指令
逻辑运算类AND、ORR、EOR、BIC按位与、或、异或、位段清零
数据序转类REV、REVSH、REVH反转字节序
扩展类SXTB、SXTH、UXTB、UXTH无符号扩展字节、有符号扩展字节
………………

寻址方式

立即数寻址

操作数直接通过指令给出。用“#”作为立即数的前导标识符。M4微处理器的立即数范围是0x00~-0xFF。例如:

	MOV 	R0, # 0xFF 		//立即数0xFF装入R0寄存器
	SUB		R1, R0, # 1		//R1←R0 - 1
寄存器寻址

操作数来自寄存器。例如:

	MOV 	R0, R1				//将R1寄存器内容装入R0寄存器
直接寻址

操作数来自存储单元,指令中直接给出存储单元地址。指令码中显示给出数据的位数,如:字、半字、单字节。例如:

	LDR 	Rt, label				//从标号label处连续读取4字节到寄存器中
	LDRH 	Rt, label				//从地址label处读取半字到Rt中
	LDRB 	Rt, label				//从地址label处读取字节到Rt中
偏移寻址及寄存器间接寻址

偏移寻址的操作数来自存储单元,指令中通过寄存器及偏移量给出存储单元的地址。偏移量不超过4KB。偏移量为0的偏移寻址也成为寄存器间接寻址。例如:

	LDR 	R3, [PC, # 100]			//从地址(PC+100)处读取4字节到R3中
	LDR 	R3, [R4]				//以R4中内容为地址,读取4字节到R3中

机器的指令码

运行源文件

利用开发环境打开工程…\CH02-1。测试代码如下:

Label:
	MOV	R0, # 0xDE
	LDR		R0, = data_format1
	LDR		R1, = Label
	LDR 	R2, [R1]
	BL		printf

执行结果如下图:
在这里插入图片描述

执行程序所获得的信息

从上图现实的内容可以看出,标号代表的地址为0900D87E,这就是指令MOV R0,# 0xDE机器码要存放的开放地址,各地址存储内容如下表:

地址0800D87E0800D87F0800D8800800D881
内容4FF0DE00

STM32数据存储采用的是小段模式,即将2个字节以上的一个数据的低字节放在存储器低地址单元,高字节放在高地址单元。

基本指令分类解析

数据传送类指令

有两种情况:一是取存储器地址空间中的数传送到寄存器中,二是将寄存器中的数传送到另一寄存器或存储器地址空间中

取数指令

编号指令说明
(1)LDR Rt, [< Rn | SP > {, #imm }]从地址{ SP/Rn + # imm}处,取字到Rt中,imm = 0, 4, 8, …, 1020
LDR Rt, [Rn, Rm]从地址Rn + Rm处读取字到Rt中
LDR Rt, label从标号label指定的存储器单元取数到寄存器,标号label必须在当前指令的-4~4KB范围内,且应4字节对齐
(2)LDRH Rt, [Rn {, #imm}]从地址{Rn + #imm}处,取半字到Rt中,imm = 0, 2, 4, …, 62
LDRH Rt, [Rn, Rm]从地址Rn + Rm处读取半字到Rt中
(3)LDRB Rt, [Rn {, #imm}]从地址{Rn + #imm}处,取半字到Rt中,imm = 0~31
LDRB Rt, [Rn, Rm]从地址Rn + Rm处读取字节到Rt中
(4)LDRSH Rt, [Rn, Rm]从地址Rn + Rm处读取半字到Rt中,并带符号扩展至32位
(5)LDRSB Rt, [Rn, Rm]从地址Rn + Rm处读取字节到Rt中,并带符号扩展至32位
(6)LDM Rt{ ! }, reglist从地址Rn处读取多个字, 加载到reglist列表寄存器中,每读一个字后Rn自增一次

存数指令

Rt,Rn,Rm必须为R0~R7中的一个

编号指令说明
(7)STR Rt, [< Rn | SP > {, #imm }]把Rt中的字存储到地址SP/Rn + #imm处,imm = 0, 4, 8,…, 1020
STR Rt, [Rn, Rm]把Rt中的字存储到地址Rn + Rm处
(8)STRH Rt, [Rn {, #imm}]把Rt中的低半字存储到地址SP/Rn + #imm处,imm = 0, 2, 4, …, 62
STRH Rt, [Rn, Rm]把Rt中的低半字存储到地址Rn + Rm处
(9)STRB Rt, [Rn {, #imm}]把Rt中的低字节存储到地址SP/Rn + #imm处,imm = 0~31
STRB Rt, [Rn, Rm]把Rt中的低字节存储到地址Rn + Rm处
(10)STM Rn!, reglist存储多个字到Rn处,每存一个字后Rn自增一次

寄存器间数据传送指令

编号指令说明
(11)MOV Rd, RmRd←Rm,Rd只可以是R0~R7
(12)MOVS Rd, # imm功能同MOV, 且影响N、Z标志
(13)MVN Rd, Rm将寄存器Rm中的数据取反,传送给寄存器Rd,影响N、Z标志

其他指令请参考书籍,在此不再罗列

汇编语言的基本语法

汇编语言源程序以行为单位进行设计,每行最多可以包含一下4部分

标号:操作码操作数注释

汇编语言的格式

标号

  1. 如果一个语句有标号,则标号必须书写在汇编语句的开头部分
  2. 可以组成标号的字符有字母A ~ Z、 a ~ z、数字0 ~ 9、下划线(_),美元符号($),但开头的第一个符号不能为数字和 $
  3. 编译器对标号中字母的大小写敏感,但指令不区分大小
  4. 标号长度基本不受限制,但实际使用时通常不超过20个字符。
  5. 标号后必须带冒号(:)
  6. 一个标号在一个文件(程序)中只能被定义一次,否则出现重复定义,不能通过编译
  7. 一行语句只能有一个标号,编译器将把当前程序计数器的值赋给该标号

操作码

操作码包括指令码和伪指令。
对于有标号的行,必须至少用一个空格或制表符将标号与操作码隔开;对于没有标号的行,不能从第一列开始写指令码,应以空格或制表符开头。

操作数

操作数可以使地址,标号或指令码定义的常数,也可以是有伪运算符构成的表达式。
如果一条指令或伪指令有操作数,则操作数与操作码之间必须用空格隔开书写。操作数多于一个的,操作数之间用逗号分隔。操作数也可以是M4内部寄存器,或者另一条指令的特定参数。
操作数一般都有一个存放结果的寄存器,这个寄存器在操作数的最前面

1、常数标识
编译器识别的常数有十进制、十六进制(0x)、二进制(0b)
2、“#”表示立即数
一个常数前添加“#”表示一个立即数;不加“#”时,表示一个地址。
3、圆点
如果圆点(.)单独出现在语句操作码之后的操作数位置上,则代表当前程序计数器的值被放置在圆点的位置。
4、伪运算符
略。详情请查阅资料

注释

类似于C语言

常用伪指令简介

在CCS开发环境下,所有的汇编命令都是以“.”开头的

系统预定义的段

C语言程序在经过gcc编译器最终生成.elf格式的可执行程序。.elf可执行程序是以段为单位来组织文件的。通常划分为如下三个段:

	.text				@只读的代码区
	.data				@可读可写的数据区
	.bss				@是可读可写且没有初始化的数据区

常量的定义

常量的定义可以使用.equ汇编指令,例如:

	.equ	_NVIC_ICER,	0xE00E180
	...
	LDR		R0, = _NVIC_ICER				@将0xE00E180放到R0中

常量的定义还可以使用.set汇编指令,例如:

	.set 	_NVIC_ICER,	0xE00E180

程序中插入常量

插入数据的类型伪指令
.word
半字.hword
字节.byte
字符串.ascii.asciz
		LDR R3, = NUMBER
		LDR R4, [R3]
		...
		LDR R0, = HELLO_TEXT
		BL	PrintText
		...
		ALIGN 4
	NUMBER:
		.word	0x123456789
	HELLO_TEXT:
		.asciz 	"hello\n"

条件伪指令

.if条件伪指令后面紧跟一个恒定的表达式,并且最后要以.endif结尾。中间如果有其他条件,可以用.else编写汇编语句。
.ifdef标号表示如果标号被定义,则执行下面的代码。

文件包含伪指令

	.include "filename"

其他常用伪指令

(1).section:用户可以通过该指令来自定义一个段

	.section .isr_vector, "a"		@定义一个.isr_vector段,"a"表示允许段

(2).global:用来定义一个全局符号

	.global	symbol

(3).extern:.extern symbol 声明symbol为外部函数,调用时可以遍历所有文件找到该函数并使用

	.global	main
	bl		main

(4).align:通过填充字节使当前位置满足一定的对齐方式
(5).end:声明汇编文件的结束
其余详见《GNU汇编语法》

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

嵌入式学习札记(基于STM32L431) 一、ARM Cortex-M4微处理器 的相关文章

  • MATLAB 2018b 安装 mexopencv (VS 2017 编译)

    MATLAB 2018b 安装 mexopencv VS 2017 编译 之前电脑上装的是MATLAB 2016b 没办法识别VS 2017 虽然官方说有补丁解决这个问题 但还是下了最新的2018b 2018b 识别VS 2017 是没问题
  • Mybatis搞五下(分页、缓存)

    Mybatis搞五下 xff08 分页 缓存 xff09 上篇博客我们讲了动态SQL xff0c 一一多多和延迟加载问题 xff0c 这篇我们讲点轻松的东西 xff0c 关于分页插件pageHelper和Mybatis面试常问的缓存问题 M
  • 03、postman前置脚本

    postman前置脚本是指在Pre requests Script中编写的js脚本 xff0c 一个请求在发送之前 xff0c 会先去执行Pre Request Script xff08 前置脚本 xff09 中的代码 xff0c 可以是为
  • Python3爬取淘宝网商品数据!

    分析淘宝网 这次选择的是淘宝网热卖而不是淘宝网 xff0c 二者虽然名字有不同 xff0c 但是数据还是一样的 xff0c 区别就在于前者把后者的所有店铺和商品的海量数据按照销售量 好评度 信誉度综合测评 重新计算 重新排序展现给买家的一个
  • Python实现淘宝准点抢单!双十一秒杀神器啊!还不来学?

    一 ChromeDriver的安装 若想使用Selenium成功调用Chrome浏览器完成相应的操作 xff0c 需要通过ChromeDriver来驱动 我们在下载之前先来确认下我们使用的Chrome浏览器版本 只需要红框内几位相同即可 根
  • 【点云系列】 场景识别类导读

    文章目录 1 背景知识2 定义3 传统方法4 基于深度学习的方法5 其他参考 xff1a 终于可以简单写一下这一块的导读了 xff0c 拖了一个多周了 希望可以帮助到大家 xff1b xff09 1 背景知识 点云检索 xff08 poin
  • 异常检测综述(Anomaly Detection: A Survey)

    Anomaly Detection A Survey 异常检测综述 xff1a 异常检测是一个重要的问题 xff0c 已经在不同的研究领域和应用领域进行了研究 许多异常检测技术是专门为某些应用领域开发的 xff0c 而其他技术则更为通用 本
  • 基于Prometheus和k8s搭建监控系统

    文章目录 1 实验环境2 Prometheus介绍 xff1f 3 Prometheus特点3 1 样本 4 Prometheus组件介绍5 Prometheus和zabbix对比分析6 Prometheus的几种部署模式6 1 基本高可用
  • STM32F4 | 窗口门狗(WWDG)实验

    文章目录 一 STM32F4 窗口看门狗简介二 硬件设计三 软件设计四 实验现象五 STM32CubeMX 配置 WWDG 在本章中 xff0c 我们将使用窗口看门狗的 中断功能来喂狗 xff0c 通过 DS0 和 DS1 提示程序的运行状
  • deepin15.11系统下使用源码包(tar.xz)安装MySQL 8.0+(补充)

    1 下载MySQL的安装包 1 1 进入官网 xff0c 找到下载 官网地址 mysql官网 1 2 找到下载入口 1 3 选择这个 1 4找到适合自己电脑系统版本 2 安装 配置MySQL和创建mysql用户 注意 最好使用root安装和
  • 基于docker部署prometheus

    1 prometheus架构 Prometheus Server 收集指标和存储时间序列数据 xff0c 并提供查询接口 ClientLibrary 客户端库 Push Gateway 短期存储指标数据 主要用于临时性的任务 Exporte
  • Prometheus监控实战系列二十:监控Kubernetes集群(下)

    本文承接上篇 xff0c 在本篇中我们会讲解Prometheus如何应用基于Kubernetes的服务发现功能 xff0c 检索目标信息并进行监控 在监控策略上 xff0c 我们将混合使用白盒监控与黑盒监控两种模式 xff0c 建立起包括基
  • RT-Thread 简介及架构

    RT Thread xff0c 全称是 Real Time Thread xff0c 顾名思义 xff0c 它是一个嵌入式实时多线程操作系统 xff0c 基本属性之一是支持多任务 xff0c 允许多个任务同时运行并不意味着处理器在同一时刻真
  • 进程的结构

    什么是进程 UNIX标准 xff08 特别是IEEE Std 1003 1 2004年版 xff09 把进程定义为 一个其中运行着一个或多个线程的地址空间和这些线程所需要的系统资源 目前 xff0c 可以把进程看作正在运行的程序 像Linu
  • 【代码小坑】梯度回传为0

    记录一下训练过程中遇到的问题 xff0c 由于这个问题我花了很长时间才解决 xff0c 所以值得记录 先给出结论 xff1a tensor转换成numpy后会丢失梯度 xff0c 导致回传出现问题 由于原代码不容易理解 xff0c 简单用个
  • (超详细)零基础如何学习操作系统---操作系统书籍推荐

    直接先给出路线书籍 编码 隐匿在计算机软硬件背后的语言 汇编语言 x86从实模式到保护模式 操作系统导论 操作系统真象还原 查漏补缺 1 编码 隐匿在计算机软硬件背后的语言 对于完全不懂计算机的朋友 xff0c 这本书可以让你对计算机有一个
  • 多种形式ICP问题的ceres实例应用

    一家之言 xff0c 仅作分享 xff0c 如有不合理或需要改进的地方 xff0c 欢迎各位讨论 ICP方法主要解决空间点云3D 3D的运动估计问题 xff0c 已知 xff1a t 1 t 1 t 1 和
  • git配置以及git-cola使用教程

    git安装 打开终端 xff0c 输入sudo apt get install git git配置 配置用户名 git config global user name 34 user name 34 配置邮箱 git config glob
  • C++ 手撸简易服务器

    本文使用上一期写的反射类 xff0c 另外我发现 lt WinSock2 h gt 这个头文件里有RegisterClass 这个结构 xff0c 还有typedef RegisterClass RegisterClassW这句话 这都能重
  • STM32CubeMX实战教程(一)——软件入门

    软件入门 前言新建工程界面简介MCU外设配置时钟树工程设置工具生成代码代码分析main cgpio cstm32f4xx it c 程序下载现象 结语 前言 STM32Cube 是一个全面的软件平台 xff0c 包括了ST产品的每个系列 平

随机推荐

  • STM32F4 | 定时器中断实验

    文章目录 一 STM32F429 通用定时器简介二 硬件设计三 软件设计四 实验现象五 STM32CubeMX 配置定时器更新中断功能 这一章介绍如何使用 STM32F429 的通用定时器 xff0c STM32F429 的定时器功能十分强
  • 相机标定和ORBSLAM2/VINS测试

    目录 一 相机标定1 1 标定目的1 2 常见模型介绍1 2 1 相机模型1 2 2 畸变模型 1 3 双目标定1 3 1 常见标定工具及对应使用场景1 3 2 Kalibr标定1 3 3 opencv双目标定1 3 4 basalt标定
  • matlab安装教程

    MATLAB xff08 矩阵实验室 xff09 是MATrix LABoratory的缩写 xff0c 是一款由美国The MathWorks公司出品的商业数学软件 MATLAB是一种用于算法开发 数据可视化 数据分析以及数值计算的高级技
  • 软件工程结构化分析

    需求分析的概念 需求分析是软件定义时期的最后一个阶段 xff0c 它的基本任务是准确的回答 系统必须做什么 这个问题 也就是对目标系统提出完整 准确 清晰 具体的要求 在需求分析阶段结束之前 xff0c 系统分析员应该写出软件需求规格说明书
  • 树莓派忘记密码 vnc登陆显示‘No configured security type is supported by 3.3 viewer’的问题解决办法

    树莓派忘记密码以及部署VNC 1 修改密码 需求你的树莓派有屏幕 xff0c 没有屏幕的可以百度其他解决方案了一把键盘 树莓派吃灰了很久 xff0c 最近由于有新的需求 xff0c 就拿出来玩耍一下 首先是第一个问题 xff0c 如何查看i
  • imx6ull 正点原子设备树适配韦东山的开发板 (一)顺利启动,配置led,button

    设备树在公司经常用到 有时候很多驱动编写也就是替换设备树 所以拿韦老师的板子练手设备树 这次尝试直接拿正点的设备书改成韦老师的板子能用 对比 正点原子的设备树结构图 韦东山的设备树结构图 从因为蓝色的是开发板厂商对开发板自己的优化 所以我们
  • 一文了解目标检测边界框概率分布

    一文了解目标检测边界框概率分布 概率建模 众所周知 xff0c CNN的有监督学习通常是建立在给定训练数据集之上的 xff0c 数据集的标签 也称为GT xff0c 决定了人类期望模型学习的样子 它通过损失函数 优化器等与CNN模型相连 因
  • Kalibr安装教程

    系统 xff1a Ubuntu18 04 首先 xff0c 需要安装好gcc g 43 43 cmake ros xff0c 如果没有 xff0c 可使用如下命令一键安装 sudo apt get install gcc g 43 span
  • 程序员:每一份不忘初心的情怀, 都是对技术的追求

    1 真正的情怀 xff0c 是从不矫情 这几年 情怀 大约快成了贬义 创业讲情怀 xff0c 产品讲情怀 xff0c 好像没点情怀都不好意思出门见人 我们曾经充满热情 xff0c 是一位开源软件倡导者 xff0c 我们崇尚全栈工程师才有未来
  • HTML代码简写方法

    原文链接 xff1a HTML代码简写方法 大写的E代表一个HTML标签 1 E 代表HTML标签 2 E id 代表id属性 3 E class 代表class属性 4 E attr 61 foo 代表某一个特定属性 5 E foo 代表
  • Git远程分支

    远程分支 远程分支是位于远程仓库的分支 xff0c 我们通常会用远程分支来更新本地分支 xff0c 然后在本地进行修改 xff0c 最后将修改的结果同步到远程分支上 除此之外 xff0c 我们还需要搞清楚远程跟踪分支和跟踪分支的概念 远程跟
  • STM32F4 | PWM输出实验

    文章目录 一 PWM 简介二 硬件设计三 软件设计四 实验现象五 STM32CubeMX 配置定时器 PWM 输出功能 上一章 xff0c 我们介绍了 STM32F429 的通用定时器 TIM3 xff0c 用该定时器的中断来控制 DS1
  • 基于大疆RM3508电机的串级PID(角度环+速度环)

    1 前言 最近参加ROBOCON xff0c 我负责编写传球机器人 xff0c 由于传球机构需要一个电机转固定角度来带动球 xff0c 所以便用大疆3508电机通过串级PID来实现 xff0c 不得不说3508电机还是真的强 xff0c 先
  • ROS三种通信方式之服务通信

    一 服务通信的理论模型 服务通信也是ROS中一种极其常用的通信模式 xff0c 服务通信是基于请求响应模式的 xff0c 是一种应答机制 也即 一个节点A向另一个节点B发送请求 xff0c B接收处理请求并产生响应结果返回给A 就像是服务器
  • 滑模控制理论(SMC)

    滑模控制理论 Sliding Mode Control SMC 滑膜控制理论是一种建立在现代控制理论基础上的控制理论 xff0c 其核心为李雅普诺夫函数 xff0c 滑膜控制的核心是建立一个滑模面 xff0c 将被控系统拉倒滑模面上来 xf
  • ROS OpenRAVE 常用逆解库 ikfast (应用于UR机械臂)

    ArmKine cpp include 34 armKine h 34 include lt math h gt include lt stdio h gt include lt corecrt math defines h gt defi
  • Fast and High Quality Image Denoising via Malleable Convolution阅读笔记

    论文 xff1a Fast and High Quality Image Denoising via Malleable Convolution arXiv xff1a https arxiv org abs 2201 00392 Abst
  • 浅谈java继承机制——通过super调用父类方法

    最近在看代码的时候遇到一个天坑 xff0c 由于习惯性思维 xff0c 可能大部分人都会掉近这个坑 xff0c 所以拿出来记录一下 子类使用super调用的父类方法里 xff0c 再调用父类的方法 先来看一段代码 xff08 该段代码只是作
  • ORB_SLAM2运行KITTI数据集

    在前文我们已经安装运行了ORB SLAM2 xff0c 下载和编译 xff08 包括报错 xff09 在文章 xff1a ORB SLAM2下载编译及运行EuRoC数据集 浅梦语11的博客 CSDN博客 euroc数据集下载 并且我们使用运
  • 嵌入式学习札记(基于STM32L431) 一、ARM Cortex-M4微处理器

    ARM Cortex M4微处理器 写在前面ARM Cortex M4微处理器简介ARM Cortex M4微处理器内部结构概要位数总线结构中断控制存储器保护低功耗内部寄存器 寻址方式与机器码获取方法指令保留字简表与寻址方式指令保留字简表寻