目录

ARM处理器的八种寻址方式

1.立即数寻址

2.寄存器寻址

3.寄存器间接寻址

4.寄存器移位寻址

5.基址变址寻址

6.多寄存器寻址

7.相对寻址

8.堆栈寻址

9.GNU汇编伪指令

异常中断处理

1.7种异常源

2.异常向量表


ARM处理器的八种寻址方式

1.立即数寻址

立即寻址,操作数本身就在指令中给出,并且指令中的立即数是由一个8bit的常数移动4bit偶数位得到的(循环右移),我们可以通过这个来判断立即数的合法性。

MOV R0,#9

MOV R1,#0x09

MOV R2,$9

十六进制立即数#后面要加0x

二进制数要加0b

十进制默认不加

八进制要加0

如何判断立即数合法性:

将该立即数写成二进制,将包含所有1的最短路径选出来,如果该路径长度大于8(循环右移得到的目标数间隔<=8也可以,比如0xf000000f)那么一定不合法,然后我们再左右两边同时去除偶数个0得到目标数即为合法

举例:0x104

将其写为二进制 000100000100,可以看到我们包含所有1的最短路径为1000001,小于8位,我们两边同时去除偶数个0可以得到我们的目标八位数01000001,循环右移得到我们的立即数所以是合法的。

2.寄存器寻址

寄存器寻址就是利用寄存器中的数值作为操作数,这种寻址方式是各类微处理器经常采用的一种方式。

例子:

MOV R0,R1 //R0=R1

ADD R0,R1,R2 //R0=R1+R2

3.寄存器间接寻址

寄存器间接寻址就是以寄存器中的值作为操作数的地址,而操作数本身放在存储器中

LDR R0,[R1]

4.寄存器移位寻址

寄存器移位寻址的操作由寄存器中的数值相应移位而得到的,移位的方式在指令中以助记符给出

移位数可用立即数或寄存器给出

MOV R1,#7

MOV R2,#1

ADD R0,R1,R2,LSL #2 //R0=R1+R2<<2

5.基址变址寻址

基址变址寻址就是将基址寄存器的内容与指令中给出的偏移量相加,得到一个有效的操作数的地址。通常用于访问连续的地址空间

前索引  LDR  R0 ,【R1,#4】等价于r0=*(r1+4)

自动索引 LDR R0,【R1,#4】! 等价于 r0=*(r1+4), r1=r1+4

后索引  LDR R0,【R1】,#4 等价于 r0=*r1,r1=r1+4

下面我们来看一个代码示例:

.textldr r0,=buf@ldr默认从地址上取4字节@【r0,#12】表示r0+12,12表示12个字节@ldr r1,[r0,#12] @r1=*(r0+12)mov r10,#1 loop:cmp r10,#5 ldrle r1,[r0],#4 @后索引 r1=*r0,r0=r0+4addle r10,#1 @le为条件码,小于等于ble loop @跳转循环
.data
buf:.word 5,3,1,4,2 @word类型为4个字节.end

6.多寄存器寻址

多寄存器寻址可实现一条指令完成多个寄存器值的传送,最多可以一次传送16个通用寄存器的值,连续的寄存器“-”连接,否则用,分割

xx可以是:ia,ib,da,db

ldmxx r0! ,{r1-r5}

stmxx r0!,{r1-r5}

看一段代码:

.textldr r0,=buf@多寄存器寻址,基址不变,连续取出4字节ldmia r0,{r1-r5}@r0基址自动更新@ldmia r0!,{r6-r11}@基地址不变,将r1-r5五个寄存器的内容写入r0对应的地址上stmia r0,{r1-r5}
.data
buf:.word 5,3,1,4,2.end

7.相对寻址

以PC的当前值为基地址,指令中的地址标号为偏移量,两者之和得到操作数的地址

8.堆栈寻址

堆栈寻址是一种数据结构,按先进后出的方式操作,R13(SP)寄存器指示当前的栈顶位置,ARM处理器支持4种堆栈操作方式(FD,FA,ED,EA),ATPCS标准规定使用FD栈。

入栈:stmfd  sp!,{r0-r12} (!表示会自动偏移)

出栈:ldmfd sp!,{r0-r12}(^表示会恢复spsr到cpsr状态寄存器)

一般堆栈寻址用于处理中断异常,将下一条指令地址LR入栈,在恢复的时候出栈给PC

我们来看一段代码:

.textldr r0,=bufmov r1,#8mov r2,#9mov r3,#10@sp栈顶指针,每入栈一个数据,sp自动向小地址方向偏移@所以必须将sp指向缓冲区末尾ldr sp,=buf_end@入栈:寄存器从右向左依次入栈stmfd sp!,{r1-r3}NOPNOP@出栈:寄存器从左往右依次出栈,先进后出ldmfd sp!,{r5,r6,r7}NOPNOP
.data
buf:.space 5*4buf_end:.end

9.GNU汇编伪指令

异常中断处理

1.7种异常源

七种类型的异常按优先级从高到低为:复位异常,数据异常,快速中断异常,外部中断异常,预取异常,软中断异常,未定义指令异常。这决定了多个中断源递交中断申请时的中断控制器对中断源的响应优先级别!

2.异常向量表

当异常发生时,处理器会把PC设置为一个特定的存储器地址。这一地址放在被称为向量表的特定地址范围内,向量表的入口是一些跳转指令,跳转到准们处理某个异常或中断的子程序。

为什么使用异常向量表呢:因为异常的产生是随机的,而每一种异常都需要处理,所以接口无法确定,所以需要硬件指定一个固定位置,但是零散不好,所以把异常的入口集中到一个区域分别存放跳转指令,跳转到对应的处理程序(地址为0-1c,可以通过协处理器更改)

我们来看一段代码:

.text_start:@异常向量表的开始@上电时,cpu默认在异常向量表的0地址处取址
b reset             @ 0x00 上电复位异常         SVC
NOP                 @ 0x04 未定义指令异常       UNDEF
ldr pc,_swi_handle  @ 0x08  软中断异常          SVC
NOP                 @ 0x0c 预取指令异常         abort
NOP                 @ 0x10 数据异常             abort
NOP                 @ 0x14 保留位
NOP                 @ 0x18 IRQ低优先级中断异常  IRQ
NOP                 @ 0x1c FIQ高优先级中断异常  FIQ@标准写法
_swi_handle:
@异常处理函数往往不在当前文件,为了突破当前文件32M的空间限制
@我们将文件名放到 .long的空间中去.long swi_handle
@异常处理
swi_handle:@1.进栈,保护现场stmfd sp!,{r0-r12,lr}
@2.出栈恢复现场,^自动恢复spsr到cpsrldmfd sp!,{r0-r12,pc}^
reset:ldr sp,=stack_top @栈顶@将svc切换成user模式,模拟用户程序mrs r0,cpsrbic r0,#0x03msr cpsr,r0NOP@产生软中断指令@1.cpu会将cpsr自动保存到spsr寄存器@2.处理器由user模式进入到SVC模式@3.lr保存下条指令的地址swi 3NOP
.data
buf:.space 125*4stack_top:.end

上述代码我们通过软中断来模拟出现中断时的处理步骤,cpu会将cpsr自动保存到cpsr寄存器种,lr会保存下一条指令地址方便中断处理完成后恢复到之前状态,处理器会由user模式进入到svc模式,完成中断处理后,会将lr出栈给pc,并自动将spsr的内容给到cpsr,还原到中断之前的状态。

我们用两张图来展示这个过程:

在建立异常向量表时一般我们有下面这样的标准:

下面我们展示一段代码通过软中断来模拟系统调用:


.text
_start:@ 上电时,cpu默认在异常向量表的 0地址处取址 b reset                    @ 0x00 上电复位异常          SVCNOP                      @ 0x04 未定义指令异常         UNDEFldr pc,_swi_handler        @ 0x08 软中断异常           SVCNOP                      @ 0x0c 预取指令异常          abortNOP                        @ 0x10 数据异常                abortNOP                        @ 0x14 保留位NOP                      @ 0x18 IRQ低优先级中断异常 IRQNOP                      @ 0x1c FIQ高优先级中断异常 FIQ_swi_handler:@ 异常处理函数往往不在当前文件,@ 为了突破当前文件32M的空间限制.long swi_handler@ 进行异常的相关处理
swi_handler:        @ 进栈,保护现场stmfd sp!, {r0-r12, lr}@ swi机器码,swi指令所在地址为 lr-4ldr r0, [lr, #-4]@ 取出机器码中的中断号 0~23and r0, r0, #0xffffffcmp r0, #1@ bleq ....cmp r0, #2@ bleq ....cmp r0, #3@ bleq ....@ 出栈,恢复现场, ^自动恢复spsr到cpsrldmfd sp!, {r0-r12, pc}^reset:ldr sp, =stack_top@ 将svc切换成 usr模式,模拟用户程序mrs  r0, cpsrbic r0, #0x3msr cpsr, r0NOP@ swi软中断:@  1、cpu会将cpsr自动保存在spsr寄存器中,@  2、处理器由 usr 模式 进入svc模式,@     3、lr 保存下条指令的地址swi 1NOPswi 2NOPswi 3NOP.data
buf:.space 125*4
stack_top:
.end

根据取出指令码中对应的中断号来进行判断进行对应的处理程序。

ARM结构体系3:ARM指令的寻址和异常中断处理相关推荐

  1. ARM结构体系和接口技术

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.ARM简介 二.ARM体系架构 2.1.内核 寄存器 工作模式 异常 2.2.指令 简介 汇编指令 指令的01编码 ...

  2. ARM结构体系5:串行通信(双线UART)和看门狗

    在通信领域内,有两种数据通信方式:并行通信和串行通信,串口的数据传输是以串行方式进行的,串口在数据通信中,一次只传输一个比特的数据,串行数据的传输速度用bps或波特率来描述. 常用术语: 1.单工(s ...

  3. Linux——Linux驱动之基本理论常识总结(什么是Linux驱动?Linux驱动需要掌握哪些?ARM处理体系架构及前世今生)

     [系列专栏]:博主结合工作实践输出的,解决实际问题的专栏,朋友们看过来! <QT开发实战> <嵌入式通用开发实战> <从0到1学习嵌入式Linux开发> 目录 0 ...

  4. ARM那些事儿和ARM培训

    很多人都知道ARM,但未必全面了解ARM"其人""其事",本文尝试回答:ARM是什么?ARM都学习那些知识?ARM培训公司都培训哪些ARM技术? 首先介绍ARM ...

  5. 【嵌入式开发】ARM 芯片简介 (ARM芯片类型 | ARM处理器工作模式 | ARM 寄存器 | ARM 寻址)

    作者 : 韩曙亮 博客地址 : http://blog.csdn.net/shulianghan/article/details/42375701 相关资源下载 :  -- 三星 ARM Archit ...

  6. x64 结构体系下的内存寻址

    转载请注明出处:http://www.cnblogs.com/lanrenxinxin/p/4735027.html 在阅读NewBluePill源码的时候,看内存的那一块简直头疼,全是x64下的寻址 ...

  7. ARM嵌入式体系架构(理论篇)

    [基础知识] (1)电路中的逻辑状态:0代表的是低电平,1代表高电平 (2)半导体元开关: [1]二极管 单向导通性 普通二极管 发光二极管 光敏二极管 稳压二极管 [2]三极管(开关特性) C :集 ...

  8. ARM汇编之跳转指令

    ARM汇编语言之跳转指令 前言 ARM架构在当今主流的芯片中无论是MCU还是SOC都占有很大的市场,因此基于ARM架构的汇编语言对于嵌入式软件开发人员而言,其实也是一项必须掌握的基本功. " ...

  9. 【ARM学习笔记】ARM汇编指令:B、BL、BX、BLX的区别

    文章目录 1 ARM的跳转指令介绍 2 ARM的4个跳转指令 2.1 B 指令 2.2 BL 指令 2.3 BLX 指令 2.4 BX 指令 3 更多分享 1 ARM的跳转指令介绍 跳转指令用于实现程 ...

最新文章

  1. 分页控件 WebPager [ZT]
  2. 23 Python常用模块(一)
  3. Android Low Battery 低电量处理流程
  4. Android P 图形显示系统
  5. boost::safe_numerics::checked_result相关的测试程序
  6. 学会这21条,你离 Vim 大神就不远了!
  7. 【HDU - 2899】 Strange fuction(二分或三分,求导)
  8. opengl es的射线拾取
  9. 软件测试--selenium脚本编写注意点(二)
  10. 软件设计师备考错题01
  11. SpringBoot中的定时任务和异步任务
  12. 手机号码归属地数据库下载
  13. 汉字为什么能流传至今_为什么中国的文字流传至今?
  14. lisp 获取横断面数据_CAD中高程点提取横断面数据的方法
  15. WTP协议简要翻译一(dlmu2001)
  16. 【深度】NGINX Rewrite 详解
  17. Hibernate 列映射 – 解决其他类型映射命名冲突
  18. J9数字论:如何避免踩雷多头陷阱?
  19. 多组数据求最大公约数
  20. PMP 双代号网络图

热门文章

  1. 英雄联盟回放保存以及播放研究
  2. Android大厂面试题锦集(BAT TMD JD 小米)
  3. 微信8.0新版本上线,这些新功能你知道吗?
  4. 利用计算机做过什么,旧电脑零件千万别扔 重新利用竟还能做出这么多新设备...
  5. python散点图圆形区域_python中散点图
  6. HDU 5266 pog loves szh III (LAC)
  7. append() 函数--R语言
  8. swagger的分组注释
  9. hive如何查找函数并查看函数使用方法
  10. 怎么解决GIS和CAD之间的坐标与实际距离的问题?