单片机核心学习:(三)ARM架构(中)

目录

一、ARM汇编

1、ARM汇编概述

2、统一的汇编语言:UAL

3、汇编指令格式

4、立即数

5、ARM编译器与GCC编译器语法差异

二、ARM汇编模拟器

1、VisUAL的基本使用


一、ARM汇编

1、ARM汇编概述

(1)汇编指令集的分类:(常用的,记住这些就够了)

通过上一篇文章的示例,可以知道① ② 

单片机核心学习:(三)ARM架构(中)_第1张图片

(2)指令集的分类

单片机核心学习:(三)ARM架构(中)_第2张图片

① 怎么修改CPU使用的指令集?

       一个芯片既可以用ARM指令集,也可以用Thumb指令集,根据CPU内部程序状态寄存器里的某一位,来表示运行的指令是ARM还是Thumb指令集,如下图:

单片机核心学习:(三)ARM架构(中)_第3张图片

ARM公司发布两类指令集:

要节省空间时用Thumb指令,要效率时用ARM指令。

1)  ARM指令集,这是32位的,每条指令占据32位,高效,但是太占空间

2)  Thumb指令集,这是16位的,每条指令占据16位,节省空间

② Thumb-2指令

当我们同时使用ARM指令集和Thumb指令集时,该怎么办呢?

1)对于以前的ARM7、ARM9和现在的Cortex A7芯片,都是支持这两种指令集。

单片机核心学习:(三)ARM架构(中)_第4张图片

2)对于现在的Corte-M系列,比如M3和M4,引入了另一种指令集Thumb-2,同时支持16位、32位指令集,可以混合在一起编程。CPU自动识别。

2、统一的汇编语言:UAL

ARM公司推出了: Unified Assembly Language,UAL,统一汇编语言,你不需要去区分这些指令集。

在程序前面用CODE32/CODE16/THUMB表示指令集:ARM/Thumb/Thumb2

日常工作中,只需要这么几条汇编指令,从名字就可以猜出含义:

MOV   LDR/STR   LDM/STM   AND/OR  ADD/SUB   B/BL  DCD  ADR/LDR  CMP

单片机核心学习:(三)ARM架构(中)_第5张图片

如果想要深入学习,可以学习《ARM Cortex-M3Cortex-M4权威指南.pdf》

3、汇编指令格式

参考《DEN0013D_cortex_a_series_PG.pdf》P70《ARM Cortex-M3Cortex-M4权威指南.pdf》5

① 汇编指令可以分为几大类:数据处理内存访问跳转饱和运算其他指令

单片机核心学习:(三)ARM架构(中)_第6张图片

② 以“数据处理”指令为例,UAL汇编格式为:

  • Operation表示各类汇编指令,比如ADDMOV
  • cond表示conditon,即该指令执行的条件;
  • S表示该指令执行后,会去修改程序状态寄存器;

单片机核心学习:(三)ARM架构(中)_第7张图片

  • Rd为目的寄存器,用来存储运算的结果;
  • RnOperand2是两个源操作数

Operation表示各类汇编指令,比如ADDMOV;如下图:

单片机核心学习:(三)ARM架构(中)_第8张图片

cond有多种取值

单片机核心学习:(三)ARM架构(中)_第9张图片

4、立即数

(1)立即数

这样一条指令:  MOV   R0, #VAL ;意图是把VAL这个值存入R0寄存器。

问:VAL可以是任意值吗?

答:不可以,必须是立即数。

问:为什么?

答:假设VAL可以是任意数,”MOV  R0, #VAL”本身是16位或32位,哪来的空间保存任意数值的VAL

        所以,VAL必须符合某些规定。

单片机核心学习:(三)ARM架构(中)_第10张图片

(2)LDR伪指令

去判断一个VAL是否立即数,麻烦!并且我就是想把任意数值赋给R0,怎么办?

可以使用伪指令:

            LDR   R0,  =VAL

  • “伪指令”,就是假的、不存在的指令。
  • 注意LDR作为“伪指令”时,指令中有一个“=”,否则它就是真实的LDR(load regisgter)指令了。
  • 编译器会把“伪指令”替换成真实的指令,比如:

LDR  R0,  =0x12   

0x12是立即数,那么替换为:

MOV  R0,  #0x12

============================================

LDR  R0, =0x12345678

0x12345678不是立即数,那么替换为:

LDR  R0, [PC, #offset]          // 2. 使用Load Register读内存指令读出值,offset是链接程序时确定的

……

Label  DCD  0x12345678    // 1. 编译器在程序某个地方保存有这个值

(3)ADR伪指令

ADR的意思是:address,用来读某个标号的地址

单片机核心学习:(三)ARM架构(中)_第11张图片

示例:

ADR  R0,  Loop

Loop

    ADD  R0, R0, #1

是“伪指令”,会被转换成某条真实的指令,比如:

ADD R0, PC, #val ; val在链接时确定 

Loop

    ADD  R0, R0, #1

5、ARM编译器与GCC编译器语法差异

GCC编译器使用的是GNU Assembler ,ARM编译器是armasm。

单片机核心学习:(三)ARM架构(中)_第12张图片

二、ARM汇编模拟器

VisUAL是一款ARM汇编模拟器,下载地址:https://salmanarif.bitbucket.io/visual/downloads.html

VisUAL模拟的ARM板子如下图所示,它没有模拟外设,仅仅模拟了CPUROMRAM

单片机核心学习:(三)ARM架构(中)_第13张图片

  • 红色区域是ROM,不能读不能写,只能运行其中的程序;
  • ROM区域本来可以读的,这是VisUAL的局限;
  • RAM区域可读可写。

1、VisUAL的基本使用

① 直接写汇编代码

单片机核心学习:(三)ARM架构(中)_第14张图片

代码含义:将R1的值放到R0的数值所指的地址的值。

② 运行:全速运行、单步执行

单片机核心学习:(三)ARM架构(中)_第15张图片

然后出现错误

单片机核心学习:(三)ARM架构(中)_第16张图片

③ 修改错误

报错显示:这个值必须是寄存器、寄存器移位、立即数,加上#代表是个立即数。

点击“Reset”后修改为:

  • MOV R0, #0x20000
  • MOV R1, #0x1234

④ 单步运行:点击Step Forwards

单片机核心学习:(三)ARM架构(中)_第17张图片

再点击Step Forwards,报错,0x1234不是立即数,采用伪指令LDR

单片机核心学习:(三)ARM架构(中)_第18张图片

改为LDR    R1, =0x1234。单步运行,结果如下图:

单片机核心学习:(三)ARM架构(中)_第19张图片

⑤ 内存观察器

1)打开内存观察器

单片机核心学习:(三)ARM架构(中)_第20张图片

单片机核心学习:(三)ARM架构(中)_第21张图片

2)查看0x20000这个地址的值

单片机核心学习:(三)ARM架构(中)_第22张图片

3)点击单步运行

单片机核心学习:(三)ARM架构(中)_第23张图片

单片机核心学习:(三)ARM架构(中)_第24张图片

复杂案例:

两个数值的比较结果或存在状态寄存器

单片机核心学习:(三)ARM架构(中)_第25张图片

 

你可能感兴趣的:(单片机核心学习,编译器,单片机,arm)