目录

  • 前言。
  • 1、ARM架构
  • 1.1、RISC
  • 1.2、提出问题
  • 1.3、CPU内部寄存器
  • 1.4、汇编指令
  • ①、读内存:Load
  • ②、写内存:Store
  • ③、加减
  • ④、比较
  • ⑤、跳转
  • 1.5stm32存储器映像
  • 2、变量
  • 2.1、什么是变量
  • 2.2、全局变量与局部变量
  • 2.3、static和volatile
  • ①、static关键字
  • ②、volatile关键字


前言。



1、ARM架构

1.1、RISC

ARM芯片属于精简指令集计算机,它所使用的指令比较简单,有如下特点:

①、对内存只有读写操作

②、对于数据的运算是在CPU内部实现

③、使用RISC指令的CPU复杂度小一点,易于设计。

windows构建 ARM 架构的 Docker 镜像 windows支持arm架构_arm开发


对上面的图示的乘法运算a = a * b,在RISC中要使用四条汇编指令:

①、读内存a

②、读内存b

③、计算a*b

④、将结果写入内存

1.2、提出问题

在CPU内部,用什么来保存a、b、a*b?

1.3、CPU内部寄存器

windows构建 ARM 架构的 Docker 镜像 windows支持arm架构_架构_02

无论是cortex-M3/M4,还是cortex-A7,CPU内部都有R0、R1、…、R15寄存器;它们都可以用来“暂存”数据。

windows构建 ARM 架构的 Docker 镜像 windows支持arm架构_数据_03


通用寄存器(R0-R12):用于调用指令进行数据操作。

对于R13、R14、R15,还另有用途:

R13:别名SP (Stack Pointer),栈寄存器,用于实现堆栈指针操作,实现数据的先进后出。

R14:别名LR(Link Register),连接寄存器,用来在调用子程序时保存返回地址。

R15:别名PC(Program Counter),程序计数寄存器,用于存下一条执行的指令的地址。

1.4、汇编指令

①、读内存:Load

LDR R0,[R1,#4];读地址“R1+4”,得到的4字节数据存入R0

②、写内存:Store

STR R0,[R1,#4];把R0的4字节数据写入地址“R1+4”

③、加减

ADD R0,R1,R2 ; R0=R1+R2;
ADD R0,#1 ;R0=R0+1;
SUB R0,R1,R2 ;R0=R1-R2;
SUB R0,R0,#1;R0=R0-1

④、比较

CMP R0,R1;结果保存到PSR(程序状态寄存器)

⑤、跳转

B main ;Branch,直接跳转。
BL main;Branch and Link,先把返回地址保存在LR寄存器里再跳转。

1.5stm32存储器映像

类型

起始地址

存储器

用途

ROM

0x0800 0000

程序存储器Flash

存储C语言编译后的程序代码

0x1FFF F000

系统存储器

存储BootLoader,用于串口下载

0x1FFF F800

选项字节

存储一些独立于程序代码的配置参数

RAM

0x2000 0000

运行内存SRAM

存储运行过程中的临时变量

0x4000 0000

外设寄存器

存储各个外设的配置参数

0xE000 0000

内核外设寄存器

存储内核各个外设的配置参数

2、变量

2.1、什么是变量

变量能读能写,故保存在内存中。因为内存具有较大的存储容量和较高的读写速度,可以方便的存储和读写程序中的数据,相比之下,寄存器容量较小,且个数有限,仅能存储少量数据。所以,程序中的变量通常会先储存在内存中,然后被操作时暂存到寄存器中进行,以提高程序的运行效率.
而Flash中存储的是程序代码和常量数据,不适合存储变量数据,Flash虽然可读可写,但对其进行写操作十分复杂。

2.2、全局变量与局部变量

全局变量:在函数外部定义的变量称为全局变量,它的作用域是从定义它的位置开始,到文件结束为止。全局变量可以被整个程序访问,因此它的生命周期也很长,直到程序结束才会被销毁。全局变量的值可以在程序的任何地方修改,因此需要谨慎使用,避免造成不必要的错误。

局部变量:在函数内部定义的变量称为局部变量,它的作用域仅限于定义它的函数内部。每次函数被调用时,局部变量都会被重新初始化,函数执行完毕后,局部变量的值就会被销毁。局部变量的作用域只在函数内部,因此可以避免变量名冲突和不必要的全局变量。

2.3、static和volatile

①、static关键字

对局部变量使用static:在函数内部使用static修饰的变量称为静态局部变量,该变量只会被初始化一次,不会随着函数的退出而销毁,仍然会保持其值,下次函数被调用时,该变量的值不会被重置。静态局部变量的作用域只在函数内部,不会影响其他函数。

对全局变量使用static:在函数外部使用static修饰的变量称为静态全局变量,该变量只能被本文件中的函数访问,其他文件无法访问该变量。静态全局变量的作用域只在本文件内部,不会影响其他文件。

对函数使用static:在函数外部使用static修饰的函数称为静态函数,该函数只能被本文件中的其他函数调用,其他文件无法调用该函数。静态函数的作用域只在本文件内部,不会影响其他文件。

②、volatile关键字

volatile关键字用于告诉编译器在编译过程中不要对该变量进行优化,确保每次访问该变量时都从内存中读取数据或者将数据写入内存中,避免编译器对变量进行优化,导致变量的值不符合预期。

在多线程或者中断处理程序中,当一个变量被多个线程或者中断处理程序共享时,为了保证数据的一致性,需要使用volatile关键字。因为多个线程或者中断可能会同时访问该变量,如果不使用volatile关键字,编译器可能会对变量进行优化,导致数据的不一致性。