ARMday03(寄存器读写、栈、程序状态寄存器、软中断和异常、混合编程)

单寄存器内存读写指令

将一个寄存器中的数值写入到内存,或者从内存中读取数据放在某一个指定寄存器中

指令码和功能

1.向内存中写:

str{条件码} 目标寄存器,[目标地址]:将目标寄存器的4字节数值写入到目标地址为首地址的空间中

strh{条件码} 目标寄存器,[目标地址]:将目标寄存器的2字节数值写入到目标地址为首地址的空间中

strb{条件码} 目标寄存器,[目标地址]:将目标寄存器的1字节数值写入到目标地址为首地址的空间中

2.从内存中读:

ldr{条件码} 目标寄存器,[目标地址]:从目标地址为首地址的空间中读取4字节数据存放在目标寄存器中

ldrh{条件码} 目标寄存器 ,[目标地址]:从目标地址为首地址的空间中读取2字节数据存放在目标寄存器中

ldrb{条件码} 目标寄存器 ,[目标地址]:从目标地址为首地址的空间中读取1字节数据存放在目标寄存器中

单寄存器内存索引方式 

前索引方式

str{条件码} 目标寄存器,[目标地址,#立即数] //将目标寄存器的数据保存在目标地址+8为起始地址的内存中

ldr{条件码} 目标寄存器,[目标地址,#立即数] //从目标地址+8为起始地址的内存中读取数据保存在目标寄存器

后索引方式

str{条件码} 目标寄存器,[目标地址],#立即数 //将目标寄存器的数据保存在目标地址为起始地址的内存中,接着目标地址自加立即数大小

ldr{条件码} 目标寄存器,[目标地址],#立即数 //从目标地址为起始地址的内存中读取数据保存在目标寄存器,接着目标地址自加立即数大小

自动索引方式 

str{条件码} 目标寄存器,[目标地址,#立即数]! //将目标寄存器的数据保存在目标地址+立即数为起始地址的内存中,接着目标地址自加立即数大小

ldr{条件码} 目标寄存器,[目标地址,#立即数]! //从目标地址+立即数大小为起始地址的内存中读取数据保存在目标寄存器,接着目标地址自加立即数大小

批量寄存器的内存读写方式 

指令码以及格式

向内存写: stm 目标地址,{目标寄存器列表} 将列表中各个寄存器的数值保存在目标地址对应的地址空间中

从内存中读取 ldm 目标地址,{目标寄存器列表} 从目标地址对应的地址空间中拿数据保存到寄存器列表中各个寄存器中

注意:

1.寄存器列表中每一个寄存器之间用','分隔,如果寄存器列表中寄存器的编号连续,那么可以用-表示一定范围内的 寄存器,比如 {r1-r5}

2.无论寄存器列表中的寄存器表现形式如何,在存取数据时始终是小编号寄存器对应低地址

批量寄存器的地址增长方式 

内存读写命令后加ia后缀

先向r0数值为起始地址的内存空间中保存一个数据,然后r0数值往高地址方向增长

内存读写命令后加ib后缀

先r0数值往高地址方向增长,然后向r0数值为起始地址的内存空间中保存一个数据

内存读写命令后加da后缀

先向r0数值为起始地址的内存空间中保存一个数据,然后r0数值往低地址方向增长

内存读写命令后加db后缀

先r0数值往低地址方向增长,然后向r0数值为起始地址的内存空间中保存一个数据

栈内存的读写

栈指针寄存器:SP/R13 保存栈顶的地址

栈:本质上就是一段内存。在内存中选取一段内存作为栈内存,可以用于保存临时数据。

栈的类型

增栈:每次压栈结束,SP保存的栈顶地址往高地址方向增栈

减栈:每次压栈结束,SP保存的栈顶地址往低地址方向增栈

空栈:压栈结束后,SP保存的栈顶空间中没有有效数据

满栈:压栈结束后,SP保存的栈顶空间中有有效数据

空增栈(EA)/空减栈(ED)/满增栈(FA)/满减栈(FD)

当前ARM处理器使用的是哪种栈?满减栈

满减栈压栈出栈操作 

1.

push {寄存器列表}@压栈

pop {寄存器列表}@出栈

2.

stmdb sp!,{r1-r5}@压栈

ldmia sp!,{r6-r10}@出栈

3.

stmfd sp!,{r1-r5}@压栈

ldmfd sp!,{r6-r10}@出栈

 叶子函数

当我们在主函数中调用一个函数,被调用的这个函数中没有别的函数调用,那么 这个函数就叫做叶子函数。栈的应用------保护现场

.text  
.global _start _start:
@初始化栈ldr SP,=0X40000020b main
main:mov r1,#3mov r2,#4bl fun1add r3,r1,r2b main
fun1:
@压栈保护现场stmfd sp!,{r1,r2}mov r1,#7mov r2,#9sub r4,r2,r1@出栈恢复现场ldmfd sp!,{r1,r2}mov pc,lr   @程序返回.end 

非叶子函数

当我们在主函数中调用一个函数,被调用的这个函数中存在别的函数调用,那么 这个函数就叫做非叶子函数

.text  
.global _start _start:
@初始化栈ldr SP,=0X40000020b main
main:mov r1,#3mov r2,#4bl fun1add r3,r1,r2b main
fun1:
@压栈保护现场stmfd sp!,{r1,r2,lr}mov r1,#7mov r2,#9bl fun2sub r4,r2,r1@出栈恢复现场ldmfd sp!,{r1,r2,lr}mov pc,lr   @程序返回
fun2:stmfd sp!,{r1,r2}mov r1,#4mov r2,#8mul r4,r2,r1@出栈恢复现场ldmfd sp!,{r1,r2}mov pc,lr   @程序返回.end 

程序状态寄存器传输指令

指令的作用实现CPSR寄存器数值的读取以及数值的修改

指令码以及格式

格式:

注意:这两条指令只能对特殊功能寄存器进行操作(CPSR),不能对普通寄存器进行操作

msr CPSR,第一操作数 将第一操作数的数值写入到CPSR寄存器中

mrs 目标寄存器,CPSR 读取CPSR数值保存到目标寄存器中

软中断指令

软中断是从软件层次上模拟的硬件中断,原理和硬件中断一样。软中断触发之后CPU进行异常模式的切换(SVC),紧接着执行软中断对应的异常处理程序。

软中断指令码以及使用

swi 中断号

注意:中断号是一个由24位二进制数组成的一个整数,用于区分不同的中断

异常处理过程分析 

异常模式和异常源的对应关系

5种异常模式对应7种异常源

异常的处理过程分析(面试重点)

***********异常的处理过程********

当一个异常源产生之后CPU会进行一些工作用于程序的跳转以及异常模式的切换,这个过程分为四大步三小步

1.保存发生异常之前的CPSR的值到对应异常模式下的SPSR寄存器中

2.修改CPSR的数值

        2.1 根据实际情况设置FIQ和IRQ中断禁止 CPSR[7:6]

        2.2 修改处理器工作状态为ARM状态 CPSR[5]

        2.3 修改处理器的工作模式为对应的异常模式 CPSR[4:0]

3.保存主程序的返回地址到对应模式下的LR寄存器中

4.修改PC的值到对应异常模式下的异常向量表中

*********处理完异常之后现场的恢复过程*********

1.恢复CPSR寄存器的值为未发生异常之前的状态

2.修改PC的值为未发生异常之前的下一条指令地址 PC=LR

异常向量表 

1.异常向量表是内存空间中的一段内存。这段内存占据了32字节。这个内存被平分为8等份,一份是4字节。每一份内存对应一种异常源,有一份保留,在异常向量表内存里存放的是当前异常源对应的异常处理程序的跳转指令。当发生异常之后,CPU会修改PC的值为对应异常源在异常向量中的位置,执行这个位置中的跳转指令,去处理异常处理程序。

2.每一种异常源在异常向量表中的位置是固定,不能随便修改

3.只要设置了异常向量表的基地址,就可以根据不同异常在一场向量表中的位置找到对应异常的跳转指令

混合编程

混合编程的意义

所谓的混合编程就是c语言资源和汇编资源的相互调用

  • 一般工程会有汇编启动程序,启动程序完成堆栈的相关初始化,完毕之后才跳转到c语言的main函数
  • c语言中几乎不可以直接操作寄存器,但是有些特定场景下需要c中操作寄存器,这时候就需要c语言中嵌套汇编的语法

汇编调用C语言的函数

*****汇编文件**********
.text    
.global _start  _start: @ 1. 初始化栈指针,C代码运行必须有栈ldr sp, =0x40000820@ 2. 汇编调用c函数 @ 2.1 给C的函数传递实参值mov r0, #3   @ a = 3mov r1, #4   @ b = 4mov r2, #5   @ c = 5mov r3, #6   @ d = 6@ 2.2 汇编调用c的函数bl add_func@ 2.3 函数的返回通过r0返回,查看r0寄存器中的值loop:   b loop  .end**********c文件********************
// c代码的函数是一个全局的函数
int add_func(int a, int b, int c, int d) 
{return (a+b+c+d);
}

c语言调用汇编标签

********起始汇编文件**********
.text    
.globl _start  _start: @ 1. 初始化栈指针,C代码运行必须有栈ldr sp, =0x40000820@ 2. 汇编调用c,跳转到main函数b main
.end********c文件************
// 使用extern对函数进行声明
extern int add_func(int a, int b, int c, int d);int sum = 0;
int main()
{// 在c代码中调用汇编代码sum = add_func(1,2,3,4);while(1);return 0;
}********汇编文件**********
.text 
.global add_func  @ 将add_func函数声明为全局add_func:add r0, r0, r1add r0, r0, r2add r0, r0, r3mov pc, lr
.end

c语言内联汇编

在某一些特定的场景下需要在c语言中直接使用汇编的语法,此时需要内联汇编。内联汇编的实现需要通过asm关键字进行修饰

asm volatile("汇编指令模板\n\t"     //"\n\t"表示一条指令的结束.....:输出列表  //指令结果的输出值:输入列表  //指令的数据输入:破坏列表  //破坏列表指定我们当前可用的寄存器
);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/137435.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

最新AI系统ChatGPT源码+AI绘画系统源码+支持GPT4.0+Midjourney绘画+搭建部署教程+附源码

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统,支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美,可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如…

CSRF(跨站请求伪造)攻击演示

目录 CSRF(跨站请求伪造)攻击演示CSRF 是什么CSRF 演示项目代码CSRF 演示过程服务启动演示 CSRF(跨站请求伪造)攻击演示 CSRF 是什么 CSRF(Cross-Site Request Forgery)跨站请求伪造,是一种网络安全攻击,其目标是利用被攻击者在…

软件安全测试怎么做?如何确保软件授权安全

在数字化不断演进的今天,软件安全测试变得至关重要。它验证了软件是否容易受到网络攻击,并检验恶意或意外输入对操作的影响。安全测试的目标是保障系统和信息的安全性和可靠性,确保它们不接受未授权的输入。 一、安全测试准备 开发者必须认识…

【广州华锐互动】太空探索VR模拟仿真教学系统

随着科技的不断发展,人类对宇宙的探索欲望愈发强烈。火星作为距离地球最近的行星之一,自然成为了人类关注的焦点。近年来,火星探测取得了一系列重要成果,为人类了解火星提供了宝贵的信息。然而,实地考察火星仍然面临着…

认识计算机-JavaEE初阶

文章目录 一、计算机的发展史二、冯诺依曼体系(Von Neumann Architecture)三、CPU基本工作流程3.1 算术逻辑单元(ALU)3.2 寄存器(Register)和内存(RAM)3.3 控制单元(CU)3…

万宾科技智能井盖监测仪器助力建设数字化城市

市政公共设施建设在近几年来发展迅速,市政设备的更新换代,资产管理等也成为其中的重要一项。在市政设施建设过程中,井盖也是不可忽视的,一方面,根据传统的管理井盖模式来讲,缺乏有效的远程监控管理方法和手…

【hcie-cloud】【3】华为云Stack规划设计之华为云Stack交付综述【上】

文章目录 前言华为云Stack交付综述交付流程华为云Stack交付流程华为云Stack安装部署流程 交付工具链华为云Stack交付工具链eDesigner - 让解决方案销售更智能eDesigner配置页面 - 基本信息eDesigner配置页面 - 服务及组网配置eDesigner配置页面 - 弹性云服务器/ECSeDesigner配置…

【工具推荐】一键多平台文章发布神器推荐(免费)

hello,大家好,我是你们老朋友洛林,上一篇文章说到自己深受多平台手动发布的折磨「传送门」,准备开发一款文章多平台工具,后来联系到 Wechatsync 原作者进行了简单的沟通,下面是关于以后的一些规划&#xff…

LeetCode(1)合并两个有序数组【数组/字符串】【简单】

目录 1.题目2.答案3.提交结果截图 链接: 88. 合并两个有序数组 1.题目 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中,使合…

STM32 堆栈空间分布

参考 运行时访问__initial_sp和__heap_base 无RTOS时的情况 在以上配置的情况下,生成工程。在工程的startup.s文件中,由如下代码: Stack_Size EQU 0x400AREA STACK, NOINIT, READWRITE, ALIGN3 __Stack_top ; 自己添加 Stack_Mem…

完全零基础,教你创建数码配件小程序商城

现如今,随着数码产品的普及,数码配件市场也越来越火爆。如果你有兴趣进入这个行业,并且想要开设一家数码配件小程序商城,那么不要担心,即使你完全零基础也可以轻松实现。 首先,登录【乔拓云】网后台&#x…

城市内涝积水监测,万宾科技内涝预警监测系统

每一个城市的排水体系都是一个复杂的网络系统,需要多个部分配合协调,预防城市排水管网带来安全隐患,也因此才能在一定程度上缓解城市内涝带来的安全问题。在海绵城市建设过程中不仅要解决大部分道路硬化导致的积水无法渗透等问题,…

【架构】后端项目经典分层架构介绍

文章目录 前言分层架构项目实践示例项目结构 其他知识 前言 开发后端项目时,我们最常见的一种架构模式就是分层架构 。 所谓的分层架构,就是把系统自上而下分为多个不同的层,每一层都有特定的功能和职责,且只和自己的直接上层与…

小白学爬虫:通过商品ID或商品链接封装接口获取淘宝商品销量数据接口|淘宝商品销量接口|淘宝月销量接口|淘宝总销量接口

淘宝商品销量接口是淘宝开放平台提供的一种API接口,通过该接口,商家可以获取到淘宝平台上的商品销量数据。使用淘宝商品销量接口的步骤如下: 1、在淘宝开放平台注册并创建应用,获取API Key和Secret Key等必要的信息。 2、根据淘宝…

【Vue】【uni-app】工单管理页面实现

用的是uni-app的uni-ui拓展组件实现的 功能是对工单进行一个展示,并对工单根据一些筛选条件进行搜索 目前是实现了除了日期之外的搜索功能,测试数据是下面这个tableData.js,都是我自己手写的,后端请求也稍微写了一些,…

FPGA配置采集AR0135工业相机,提供2套工程源码和技术支持

目录 1、前言免责声明 2、AR0135工业相机简介3、我这里已有的 FPGA 图像处理解决方案4、设计思路框架AR0135配置和采集图像缓存视频输出 5、vivado工程1–>Kintex7开发板工程6、vivado工程1–>Zynq7100开发板工程7、上板调试验证8、福利:工程代码的获取 1、前…

【解决问题】---- 解决 avue-crud 表格勾选数据翻页后界面保持选中

1. 错误预览 第一页选择【7、8、9、10】 直接点击第三页未进行选择 直接点击第四页未进行选择 2. 问题总结 通过测试可以看到,页面的选择项会影响到其他页面的选择;点击保存,返回的数据却是真真选择的数据;数据在选择渲染…

【论文阅读】多模态NeRF:Cross-Spectral Neural Radiance Fields

https://cvlab-unibo.github.io/xnerf-web intro 从不同的light spectrum sensitivity获取信息,同时需要obtain a unified Cross-Spectral scene representation – allowing for querying, for any single point, any of the information sensed across spectra。…

CAN轴【禾川】

禾川CAN轴有问题。 厂家说是只能使用禾川的伺服X2EN,和X3EN 添加CAN主站: 网络: 0 波特率: 1000K 添加CAN总线: 主站: 2 同步帧: 80h 设置刷新时间 时间帧:100h 添加伺服&…

Vue el-table序号与复选框hover切换

效果图下&#xff1a; <template><div class"container"><el-tableref"multipleTable"id"multipleTable":data"person.tableData"cell-mouse-enter"cellEnter"cell-mouse-leave"cellLeave"selecti…