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,=0X40000020
   b main
main:
    mov r1,#3
    mov r2,#4
    bl fun1
    add r3,r1,r2
    b main
fun1:
@压栈保护现场
    stmfd sp!,{r1,r2}
    mov r1,#7
    mov r2,#9
    sub r4,r2,r1
    @出栈恢复现场
    ldmfd sp!,{r1,r2}
    mov pc,lr   @程序返回
   
.end 
    

非叶子函数

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

.text  
.global _start 
            

_start:
@初始化栈
   ldr SP,=0X40000020
   b main
main:
    mov r1,#3
    mov r2,#4
    bl fun1
    add r3,r1,r2
    b main
fun1:
@压栈保护现场
    stmfd sp!,{r1,r2,lr}
    mov r1,#7
    mov r2,#9
    bl fun2
    sub r4,r2,r1
    @出栈恢复现场
    ldmfd sp!,{r1,r2,lr}
    mov pc,lr   @程序返回
fun2:
    stmfd sp!,{r1,r2}
    mov r1,#4
    mov r2,#8
    mul 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 = 3
    mov r1, #4   @ b = 4
    mov r2, #5   @ c = 5
    mov 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, r1
        add r0, r0, r2
        add r0, r0, r3
        mov pc, lr
.end

c语言内联汇编

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

openvino学习(一)ubuntu20.04安装openvino2022

安装openvino2022要求 操作系统 Ubuntu 18.04 长期支持 (LTS),64 位 Ubuntu 20.04 长期支持 (LTS),64 位 软件 CMake 3.13 或更高版本,64 位 GCC 7.5.0(适用于 Ubuntu 18.04)或 GCC 9.3.0(适用于 Ubunt…

[ Linux Busybox ] flash_eraseall 命令解析

文章目录 相关结构体flash_eraseall 函数实现flash_eraseall 实现流程图 文件路径:busybox-1.20.2/miscutils/flash_eraseall.c 相关结构体 MTD 相关信息结构体 struct mtd_info_user {__u8 type; // MTD 设备类型__u32 flags; // MTD设…

一篇文章带你搞懂DNS全流程

1.DNS与CDN DNS是域名系统的缩写,它是一种将域名和IP地址相互映射的分布式数据库,能够使人更方便地访问互联网。 DNS的主要功能是将域名解析为IP地址。当你在浏览器中输入一个网址时,浏览器会向DNS服务器发送一个请求,以获取该网…

如何使用 JMeter 进行 HTTPS 请求测试?

本文将介绍如何使用 JMeter 测试 HTTPS 请求,并提供相关的技巧和注意事项。 在进行性能测试时,很多网站都采用了 HTTPS 协议。当我们测试 HTTPS 请求,如果服务端开启了双向认证,则需要客户端发送请求时带上证书。本文介绍如何在 …

换服还是掀桌?哪条才是程序员的出路?

站在时代的风口浪尖,猪都能起飞。 大数据互联网正是时代的宠儿,IT行业的发展也正如火如荼。 人人都眼红程序员的高薪资,认为他们吃着时代的红利。 但是三百六十行,行行出社畜。”996“也好,甚至"007"也罢…

软件测试面试题【2023最新合集】

收集了各大公司的面试经验,现整理出来,希望能给正在找工作的志同道合的小伙伴一些指引,本文会持续更新的哦。 1、 CPU 和 GPU的区别 一个是通用计算,一个是专用计算。 CPU主要负责操作系统和应用程序,GPU主要负责跟…

TensorFlow学习笔记--(1)张量的随机生成

张量的生成 如何判断一个张量的维数:看张量的中括号有几层 0 1 2 :零维数列 [2 4 6] : 一维向量 [ [1 2 3] [4 5 6] ] : 二维数组 两行三列 第一行数据为 1 2 3 第二行数据为 4 5 6 以此类推 n维张量有n层中括号 tf.zeros(%指定一个张量的维数%) 生成一…

汽车标定技术(二)--基于XCP的标定测量实战

目录 1.工程创建 1.1 新建工程 1.2 设备配置 1.3 标定观测 1.4 刷写 2.原始hex文件与标定文件的合并 2.1 修改memory segment file 2.2 标定量地址偏移 ​编辑 2.3 标定后与原始hex文件合并 2.4 标定后直接merge 2.5 不用对ram地址进行偏移实现hex文件合并 本文使用…

【机器学习】梯度下降预测波士顿房价

文章目录 前言一、数据集介绍二、预测房价代码1.引入库2.数据3.梯度下降 总结 前言 梯度下降算法学习。 一、数据集介绍 波士顿房价数据集:波士顿房价数据集,用于线性回归预测 二、预测房价代码 1.引入库 from sklearn.linear_model import Linear…

【Docker】设置容器系统字符集zh_CN.UTF-8退出失效:关于Docker容器配置环境变量,再次进入失效问题

设置容器系统字符集zh_CN.UTF-8退出失效:关于Docker容器配置环境变量,再次进入失效问题 修改正在运行的Docker容器内的字符集: 先进入Docker容器:docker exec -it 容器ID /bin/bash查看是否支持中文字符集:locale -a | grep zh&a…

案例 | 3D可视化工具HOOPS助力SolidWorks edrawings成功引入AR/VR技术

HOOPS中文网慧都科技是HOOPS全套产品中国地区指定授权经销商,提供3D软件开发工具HOOPS售卖、试用、中文试用指导服务、中文技术支持。http://techsoft3d.evget.com/达索系统SolidWorks面临的挑战 达索系统SolidWorks公司开发和销售三维CAD设计软件、分析软件和产品…

五、计算机网络

(一)OSI/RM 七层模型 七层模型是计算机网络的基石,整个计算机网络是构建与七层模型之上的。 在数据链路层,数据开始以帧为单位,网卡的 MAC 地址就是数据帧的地址,数据的传输开始有地址了。 局域网是工作…

国自然中标越来越难,怎样才能赢在起跑线上?

众所周知,国自然在学术界的地位和影响力不容小觑。“国自然在手,天下我有”,对于科研人来说,成功申报国自然,有助于职称评审、职业升迁,同时,获得不菲的科研经费。据了解,有些高校还…

https网站加载http资源问题

https网站加载http资源问题 前言:最近项目对接了一个第三方的平台、我们需要展示第三方平台返回来的图片资源、由于我们的服务器设置为了https、但是第三方平台返回的图片链接是 http 资源。所以就出现了图片无法加载出来的问题,在此记录一下问题的解决…

ps人像怎么做渐隐的效果?

photoshop怎么制作人像渐隐的图片效果?渐隐效果需要使用渐变来实现,下面我们就来看看详细的教程。 首先,我们打开Photoshop,点击屏幕框选的【打开】,打开一张背景图片。 下面,我们点击左上角【文件】——【…

如何在Jetpack Compose中显示PDF?

当读取和显示 PDF 的组件缺失时该怎么办? 声明式编程可以拯救你. Jetpack Compose已经存在好几年了, 但_在某些方面它的使用仍然面临挑战_. 例如, 缺少用于查看PDF的官方组件, 而为数不多的第三方库通常也是有代价的. 在我们的应用中, 我们会遇到在许多场景中显示 PDF 的需求…

1.1 HTML4

一. 前言 1. 两位先驱 艾伦麦席森图灵 二战时期,破译了德军的战争编码一英格玛。让二战提前2年结束,拯救了上千万人的生命。设立图灵奖,被后人誉为:人工智能之父。 约翰冯诺依曼 制订了现代计算机标准一一冯诺依曼体系结构。提出:计算机要…

目标检测中的评价指标

目标检测中的评价指标 将检测目标分为正样本和负样本。 真阳性(true positives , TP) : 正样本被正确识别为正样本。 假阳性(false positives, FP): 负样本被错误识别为正样本。 假阴性(false negatives, FN&#…

微服务项目,请求从发出到后端处理器的历程

点击登录按钮,发出 http://localhost:8803/service_6001/admin/login/in请求,这是一个由nginx配置的前端项目 查看配置文件,该条请求会被映射形成对http://localhost:51603/admin/login/in的post请求 upstream heima-admin-gateway {server localhost:51603; } server {liste…