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

news2024/11/26 21:37:50

单寄存器内存读写指令

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

指令码和功能

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寄存器数值的读取以及数值的修改

指令码以及格式

格式:

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"表示一条指令的结束
    .....
    :输出列表  //指令结果的输出值
    :输入列表  //指令的数据输入
    :破坏列表  //破坏列表指定我们当前可用的寄存器
);

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

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

相关文章

0X03

红包题第二弹 看到源码里面的提示 ?cmdphpinfo(); 看到源码 kk 关键点就是有两个正则表达式 第一个 preg_match("/[A-Za-oq-z0-9$]/",$cmd) 第二个 preg_match("/\~|\!|\|\#|\%|\^|\&|\*|\(|\)|\(|\)|\-|\_|\{|\}|\[|\]|\|\&q…

【MySQL日志与备份篇】其他数据库日志

其他数据库日志 文章目录 其他数据库日志1. 概述1.1 日志类型1.2 日志的弊端 2. 慢查询日志(slow query log)3. 通用查询日志(general query log)4. 错误日志(error log)5. 二进制日志(bin log)5.1 参数5.2 查看日志5.3 格式5.3.1 STATEMENT模式 (基于SQL语句的复制…

Web组件

开发者使用Vue、React等框架来使用及创建定制的组件,Web组件是浏览器原生支持的替代这些框架的特性,主要涉及相对比较新的三个Web标准。这些Web标准允许JS使用新标签扩展HTML,扩展后的标签就是自成一体的、可重用的UI组件。 1 HTML模版 Docu…

数据结构大体体系

逻辑结构 线性结构线性表一串珠子用线连起来,这就是典型的“线性存储结构”。每颗珠子之间的关系结构也很简单,包括头尾的话,它们最少有一个关系对象,而中间的珠子无论前后都只有一个关系对象,即 one-to-one栈队列字符…

webgoat-Sensitive Data Exposure 敏感信息泄露

insecure login不安全的登录 Encryption is a very important tool for secure communication 0x02 点击login,可以看到payload里的username和password,输入后点击submit即可。 这题的目的是说明,信息传输过程中需要加密,如不…

【C语言 | 符号】C语言中符号易出错的地方

😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀 🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C、数据结构、音视频🍭 🤣本文内容🤣&a…

一次简单的测试

文章现写的,部分内容有些着急 0x01 测试过程 开局登录框,没有测试SQL注入与XSS(菜鸟,测也测不出来。) 有system用户,尝试弱口令,无果! 直接namp来一下子端口探测吧 发现有3306与8888 3306 mysql测试 88…

python 之异常处理结构

文章目录 常见的异常处理表现形式1. SyntaxError2. NameError3. TypeError4. IndexError5. KeyError6. ZeroDivisionError7. FileNotFoundErrortry……except …… 结构1. try 块2. except 块示例:多个except块try……except ……else 结构结构说明:示例…

注册电气工程师(供配电)专业考试大纲纯干货分享

1.法律法规与工程管理 1.1熟悉我国工程勘察设计中必须执行法律、法规的基本要求; 1.2熟悉了解工程勘察设计中必须执行建设标准强制性条文的概念; 1.3了解我国工程项目管理的基本概念和项目建设法人、项目经理、项目招标与投标、项目承包与分包等基本要素…

MySQL 数据目录和 InnoDB 表空间补充知识:详细结构

1. 数据目录 在Ubuntu下,MySQL的数据目录为/var/lib/mysql 1.1 数据库在文件系统中的表示 (1)创建数据库时,会在数据目录下创建一个与数据库名同名的子目录。(除了information_schema这个系统数据外) &…

AVS3:双向梯度修正BGC

双向梯度修正(Bi-directional Gradient Correction,BGC)是利用双向参考块间的差值对预测值进行修正的技术。 BGC仅用于双向预测CU,设两个方向得到的单向预测值分别为pred0和pred1,修正前的双向预测值为predBI&#xf…

看完这篇,医学小白也能轻松玩转文献查阅

对医学生而言,文献查询是写论文必不可少的一环。然而这实在是一件重要但又心累的事情。你是否每次查找文献,都感觉自己在进行无意义的重复劳动;一天下来全在搜索、下载、保存;搜索引擎给出的结果太多太杂,或者找不到全…

linux C++实现线程绑定CPU

前言 嵌入式里面我们会使用到多核的cpu,随着产品芯片性能提升,我们也会有很多功能,以及很多进程产生运行,这个时候我们在任务调度调优的时候,把一些进程绑定到固定cpu运行,下面就来分享一下cpu绑定运行的过…

ubunt18.04.4 安装petalinux2022.2

安装Petalinux需要许多依赖: 安装下面的工具: sudo apt-get install net-tools sudo apt-get install xterm sudo apt-get install autoconf sudo apt-get install libtool sudo apt-get install texinfo sudo apt-get install zlib1g-dev sudo apt-get…

Android Studio报错:connect refused

参考链接: https://blog.csdn.net/qq_43213783/article/details/113936012 参考文章中说报错主要是由于代理导致的,在文件->设置->外观与行为->系统设置->HTTP代理。 方法一: 查看打开代理(前提是代理可以通网&#x…

混沌系统在图像加密中的应用(小波混沌神经网络)

混沌系统在图像加密中的应用(小波混沌神经网络) 前言一、小波混沌神经网络模型二、拓展三、python代码 前言 小波混沌神经网络是一种神经网络模型,结合了小波变换和混沌理论,用于信号处理、分类和预测。该模型基于多层前向神经网…

经典OJ题:单链表相交

目录 题目: 链表相交🍌的概念: 单链表相交🍌主要的问题: 思路的分析🍌: 问题的回答: 如何判断相交🍌: 如何寻找交点🍌: 代码演…

独立云厂商市场份额第一 | 云轴科技ZStack位居IDC云系统软件市场报告第一梯队

近日,全球IT市场研究和咨询公司IDC发布《中国云系统软件市场跟踪报告2023H1》报告,报告显示2023年上半年中国云系统软件整体市场规模达到24.08亿元,同比增长16.4%。其中,云轴科技ZStack 作为产品化的云基础软件提供商,…

Leetcode-206 反转链表

迭代法:将指针方向依次改变,定义两个指针pre和cur /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val val; }* ListNode(int val, Lis…

如何找出最优的【SVC】核函数和参数值—以乳腺癌数据集为例

在实际的工作中,有的时候我们不知道数据特征,也不知道我们的数据是线性还是非线性。因此我们需要对数据一步步进行摸索,来找到最优的核函数和参数值。接下来我们以sklearn乳腺癌数据集为例。 先来导入相应的模块: from sklearn.d…