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

2023-05-16

目录

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

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

.text
	ldr 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+4
		addle 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}

看一段代码:

.text
	ldr 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

我们来看一段代码:

.text
	ldr r0,=buf
	mov r1,#8
	mov r2,#9
	mov r3,#10
	@sp栈顶指针,每入栈一个数据,sp自动向小地址方向偏移
	@所以必须将sp指向缓冲区末尾
	ldr sp,=buf_end
	@入栈:寄存器从右向左依次入栈
	stmfd sp!,{r1-r3}
	NOP
	NOP
	@出栈:寄存器从左往右依次出栈,先进后出
	ldmfd sp!,{r5,r6,r7}
	NOP
	NOP
.data
buf:
	.space 5*4
	
buf_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到cpsr
	ldmfd sp!,{r0-r12,pc}^
reset:
	ldr sp,=stack_top @栈顶
	@将svc切换成user模式,模拟用户程序
	mrs r0,cpsr
	bic r0,#0x03
	msr cpsr,r0
	NOP
	@产生软中断指令
	@1.cpu会将cpsr自动保存到spsr寄存器
	@2.处理器由user模式进入到SVC模式
	@3.lr保存下条指令的地址
	swi 3
	NOP
.data
buf:
	.space 125*4
	
stack_top:

.end

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

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

 

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

 

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

	
.text
_start:
	@ 上电时,cpu默认在异常向量表的 0地址处取址 
	b reset					@ 0x00 上电复位异常	  		SVC
	NOP						@ 0x04 未定义指令异常  		UNDEF
	ldr pc,_swi_handler		@ 0x08 软中断异常	  		SVC
	NOP						@ 0x0c 预取指令异常	  		abort
	NOP						@ 0x10 数据异常		  		abort
	NOP						@ 0x14 保留位
	NOP						@ 0x18 IRQ低优先级中断异常	IRQ
	NOP						@ 0x1c FIQ高优先级中断异常	FIQ

_swi_handler:
	@ 异常处理函数往往不在当前文件,
	@ 为了突破当前文件32M的空间限制
	.long swi_handler


@ 进行异常的相关处理
swi_handler:		
	@ 进栈,保护现场
	stmfd sp!, {r0-r12, lr}
	
	@ swi机器码,swi指令所在地址为 lr-4
	ldr r0, [lr, #-4]
	@ 取出机器码中的中断号 0~23
	and r0, r0, #0xffffff
	cmp r0, #1
	@ bleq ....
	cmp r0, #2
	@ bleq ....
	cmp r0, #3
	@ bleq ....
	
	@ 出栈,恢复现场, ^自动恢复spsr到cpsr
	ldmfd sp!, {r0-r12, pc}^
	
reset:
	ldr sp, =stack_top
	
	@ 将svc切换成 usr模式,模拟用户程序
	mrs	r0, cpsr
	bic r0, #0x3
	msr cpsr, r0
	NOP
	@ swi软中断:
	@	1、cpu会将cpsr自动保存在spsr寄存器中,
	@ 	2、处理器由 usr 模式 进入svc模式,
	@ 	3、lr 保存下条指令的地址
	swi 1
	NOP
	swi 2
	NOP
	swi 3
	NOP
	
	
.data
buf:
	.space 125*4
stack_top:
.end

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

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

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

随机推荐

  • 火狐浏览器设置脚本

    第一步 xff0c 打开火狐浏览器 xff0c 点击如下位置 第二步 xff0c 进入扩展和主题 第三步 xff0c 在搜索框中搜Tampermonkey 第四步 xff0c 下载加入拓展 xff0c 并自动弹出页面 在用户脚本出搜寻你所需
  • 我的Linux与ROS的不眠不休:从入门到入土(三)——简单了解ROS

    学习ROS好歹先知道ROS是什么 xff0c ROS怎么做到成为机器人最值得一学的操作系统的 一 回顾下ROS的下载 1 优先配置软件与更新应用的软件源 选择科大源 2 更新完列表之后打开终端 xff0c 将科大软件源替换进source中
  • 我的Linux与ROS的不眠不休:从入门到入土(三)——hellow,ROS

    一 ROS回顾 没啥好回顾的 ros操作简单又功能强大 xff08 百度这么说的 xff09 xff0c 但学起来也没那么容易 二 Hellow xff0c ROS 上一篇说过 xff0c ROS程序员需要写的程序 xff0c 其实就是创造
  • 【linlong】Docker第二篇-常用命令(docker启动关闭、镜像拉取、容器创建启动关闭删除等常用指令)

    目录 2 Docker常用命令 2 1 帮助命令 2 2 镜像命令 2 3 搜索镜像 2 4 拉取镜像 2 5 删除镜像 2 6 容器命令 2 6 1 创建容器并启动 2 6 2 退出容器 2 6 3 启动容器 2 6 4 停止容器 2 6
  • 西门子S7-200 SMART系列PLC接线大全

    西门子S7 200 SMART系列PLC接线大全 西门子S7 200 SMART系列PLC接线大全 xff0c 电器人必须收藏 xff01 xff01 xff01 输出 模块 负载
  • 百度云离线下载含有违规内容检测方法分析

    最近国家开始一轮净网行动 xff0c 清除网上的淫秽色情信息 各大互联网厂家纷纷开始行动 xff0c 比如当年很好用的百度云离线下载就一度关闭 后来再次开启后 xff0c 就出现了这句经典词 xff0c 因含有违规内容被屏蔽无法下载 其实被
  • 基于PLC S7-200恒压变频供水系统设计

    基于PLC S7 200恒压变频供水系统设计 有Wincc仿真设计 xff0c 梯形图程序 系统主要由PLC 变频器 电动机 水阀 传感器构成 xff0c 该系统用PLC作为控制器 xff0c 将控制信号传递给变频器 xff0c 变频器控制
  • 我的首篇博客——记录学习,不忘初心

    Hello 大家好 xff01 我是阿冰 xff01 今天是2022年12月2日 xff0c 受疫情影响 xff0c 我们学校的同学都早早的回家了 xff0c 今天就是我回家的第五天 其实 xff0c 这并不算是真正意义的寒假 xff0c
  • Java标识符和关键字

    目录 前言 一 关键字 1 什么是关键字 xff1f 2 关键字的一些注意事项 二 标识符 1 什么是标识符 xff1f 2 标识符书写规范 总结 前言 在华清学习的所思所想 xff1a Java关键字及标识符 一 关键字 1 什么是关键字
  • 图为科技NVIDIA Jetson Xavier NX测评

    NVIDIA推出了世界上最小的人工智能计算机 NVIDIA Jetson Xavier NX 整个设置的大小小于普通大小的借记卡或信用卡 该模块虽然不是业务中最小的 xff0c 但它所提供的处理能力和其他质量足以弥补其尺寸 Jetson N
  • Jetson TX2 NX 模块以纳米尺寸提供 TX2 电源

    Nvidia 推出了Jetson TX2计算模块 的降速功能 xff0c 该模块位于 TX2 和低端Jetson Nano之间 Jetson TX2 NX 在与 TX2 相同的六核 CPU 和 256 核 Pascal GPU 上运行 Li
  • 无人机在行业的应用方面呈现出多元化的趋势

    随着科技的不断发展和进步 xff0c 无人机的行业应用也逐渐扩大 作为民用无人机主要细分领域之一 xff0c 测绘无人机的发展也越来越成熟 xff0c 市场规模保持高速增长 无人机在应用方面也呈现出多元化的趋势 xff0c 备受各个行业用户
  • 嵌入式能从事什么职业?

    嵌入式本身发展是很好的 xff0c 这也是大家接触它的原因 xff0c 最后大家也是想通过学习嵌入式而找到关于嵌入式开发的工作 xff0c 想必大家也应该知道嵌入式工作要求有很多 xff0c 下面就一起来看看嵌入式能从事什么职业吧 点击获取
  • 嵌入式入门学习的必要步骤

    很多新手在入门嵌入式的时候 xff0c 经常会有很多问题 xff0c 这也都是想要多多去了解嵌入式 xff0c 也害怕自己浪费了时间还没有学会嵌入式 xff0c 掌握到好方法学习嵌入式 xff0c 那么就会事半功倍 xff0c 下面一起来看
  • 逆变器原理

    逆变器是把直流电转变为交流电的一种装置 它一般包括逆变桥 控制逻辑和滤波电路组成 主要是把各种直流源转变为交流供交流负载使用 xff0c 一般直流源有蓄电池 干电池 太阳能电池等 xff0c 可以应用到不间断电源 UPS 太阳能发电转换等
  • RS-485 通讯协议简介

    与 CAN 类似 xff0c RS 485 是一种工业控制环境中常用的通讯协议 xff0c 它具有抗干扰能力强 传输距离远的特点 RS 485 通讯协议由 RS 232协议改进而来 xff0c 协议层不变 xff0c 只是改进了物理层 xf
  • 反向散射耦合RFID系统的原理及特点,带你更深入的了解

    一 反向散射耦合RFID系统 1 反向散射 雷达技术为RFID的反向散射耦合方式提供了理论和应用基础 当电磁波遇到空间目标时 xff0c 其能量的一部分被目标吸收 xff0c 另一部分以不同的强度散射到各个方向 在散射的能量中 xff0c
  • 西门子PLC,1200PLC如何接线,2分钟就能明白

    西门子PLC xff0c 1200PLC如何接线 xff0c 2分钟就能明白 西门子PLC xff0c 1200PLC如何接线 xff0c 2分钟就能明白 哔哩哔哩 bilibili
  • 2022年嵌入式开发就业前景怎么样?

    时间 xff1a 2022年5月26号 xff01 这几年嵌入式开发的发展前景可以说是非常的香 xff01 从工资和找工作的难易程度上说都是 xff01 按老师傅的说法就是 xff1a 加班不严重 xff0c 注重积累 xff0c 越往底层
  • ARM结构体系3:ARM指令的寻址和异常中断处理

    目录 ARM处理器的八种寻址方式 1 立即数寻址 2 寄存器寻址 3 寄存器间接寻址 4 寄存器移位寻址 5 基址变址寻址 6 多寄存器寻址 7 相对寻址 8 堆栈寻址 9 GNU汇编伪指令 异常中断处理 1 7种异常源 2 异常向量表 A