ARM中栈的种类与运用

1. 栈的概念

栈,本身是一段内存,程序运行时用于保存一些临时数据,如局部变量、参数、返回地址等等。

        学习了数据结构,对栈的概念相信大家都不陌生,后进先出的数据结构,即最后进栈的元素最先出栈。但是在C语言中,栈是由编译器自动管理的。这一点与堆相反,堆是由程序员手动分配和释放的,例如malloc和free。而栈是由编译器自动管理的。

        当程序调用一个函数时,编译器会为该函数的局部变量参数返回地址等信息在栈上分配一段空间,并将这些信息压入栈中。当函数执行完毕后,这些信息会被弹出栈,并回到调用该函数的位置继续执行代码。

在C语言中我们不需要了解栈的工作方式,但是学习了ARM底层架构,就要了解栈在程序中的工作过程。

2. 栈的分类

在学习数据结构,没有听说过栈还有什么分类,通常是将栈和队列一起讲的,而在底层技术中,栈其实有很多种分类,这些分类决定了栈的特点和使用方式,而C语言中不需要关心,所以我们没有了解。那么栈有哪几种分类呢?他们之间的区别是什么?

首先我们要了解,CPU要使用栈,那么就要知道栈的地址在哪?栈是由栈指针来管理的,栈指针指向栈的顶部。栈指针的地址通常由编译器或操作系统来分配,对于ARM来讲,在汇编语言中,可以使用寄存器SP来表示栈指针,所以当使用栈时,找到SP就能知道栈指针指向的地址了。

2.1 增栈与减栈

增栈:压栈操作将数据放入栈顶,栈顶指针向下移动;减栈:压栈操作将栈顶数据弹出,栈顶指针向上移动。

  • 对于增栈,存数据时,SP指向的地址越来越大;取数据时,SP指向的地址越来越小
  • 对于减栈,存数据时,SP指向的地址越来越小;取数据时,SP指向的地址越来越大

可以理解为SP最开始指向中间某个地址,增栈意味着向地址大的压入,而减栈意味着向地址小的压入。

2.2 满栈与空栈

满栈:栈指针指向最后一次压入到栈中的数据,压栈时需要先移动栈指针到相邻的位置再压栈

空栈:栈指针指向最后一次压入到栈中的数据的相邻位置,压栈时可直接压栈,之后才需要把栈指针移动到相邻位置

简单来说,

  • 对于满栈,刚开始的时候栈指针指向的地址有元素,指向的是最后一个压入栈中的数据,所以先移动栈指针,才能继续压栈。
  • 对于空栈,刚开始的时候栈指针指向的地址无元素,指向的是最后一个压入栈的数据的后一个地址,所以可以先进行压栈,后再移动栈指针。

2.3 四种栈的分类

根据2.1和2.2,我们可以知道栈的两种地址类型和两种数据方式,将这两种大类进行合并,我们可以知道,栈有四种类型:空增(EA)、空减(ED)、满增(FA)、满减(FD)对于ARM处理器一般使用满减栈

2.4 多寄存器内存访问指令的寻址方式

在寄存器中,用于将多个寄存器的数据存储到连续的一块内存中

STMIA和STMIB

这两种都是从低地址向高地址存放数据

  • STMIA:指针指向哪,就从那开始以由低到高地址存数据
  • STMIB:指针先指向的下一个地方开始,再由低到高地址存数据

STMDA和STMDB

这两种都是从高地址向低地址存放数据

  • STMDA:指针指向哪,就从那开始以由高到低地址存数据
  • STMDB:指针先指向的下一个地方开始,再由高到低地址存数据

思考:如上我们知道,ARM存储器一般使用满减栈,那么我们如何选择上述寻址方式?

回忆一下满减(FD),对于满减是先移动指针,再进行存入数据,且存入数据时,地址越来越小,可以很容易得到,满减对应的是STMDB

2.5 如何读取栈里的数据?

对于满减,后进先出,那么我们从地址低的读到地址高的,且从指针的指向开始,那么满减对应的应该是LADIA

示例代码:

	MOV R1, #1
	MOV R2, #2
	MOV R3, #3
	MOV R4, #4
	MOV R11, #0x40000020
	STMDB R11!, {R1-R4}
	LDMIA R11!, {R6-R9}
	@ STMFD R11!, {R1-R4}
	@ LDMFD R11!, {R6-R9}

因为已知是满减,所以可以直接使用FD作为结尾也是没有问题的。但是要记住,虽然可以直接使用满减后缀,但是编译器也是会自动转换成第一种方法的。

得到:

3. 栈的应用举例

3.1 叶子函数的调用

	@ 初始化栈指针
    MOV SP, #0x40000020
	
MAIN:
		MOV R1, #3
		MOV R2, #5
		BL	FUNC
		ADD R3, R1, R2
		B stop
		
FUNC:
		@ 压栈保护现场
		STMFD SP!, {R1, R2}		@ 满减栈
		MOV R1, #10
		MOV R2, #20
		SUB R3, R2, R1
		@ 出栈恢复现场
		LDMFD SP!, {R1, R2}
		MOV PC, LR

结果:

        这段代码作用是:先初始化栈指针,0x40000020初始化地址,在FUNC函数中,首先使用STMFD指令将R1和R2的值压入栈中,以保护现场。以免等下重新赋值时覆盖了原有的值。然后计算R2-R1的值,并将结果存储在R3中。最后使用LDMFD指令将R1和R2的值从栈中弹出,以恢复现场

3.2 非叶子函数的调用

	@ 初始化栈指针
    MOV SP, #0x40000020
	
MAIN:
		MOV R1, #3
		MOV R2, #5
		BL	FUNC1
		ADD R3, R1, R2
		B stop
		
@ FUNC1:
		STMFD SP!, {R1, R2, LR}		@ 满减栈
		MOV R1, #10
		MOV R2, #20
		BL FUNC2
		SUB R3, R2, R1
		LDMFD SP!, {R1, R2, LR}
		MOV PC, LR
FUNC2:
		STMFD SP!, {R1, R2}	
		MOV R1, #7
		MOV R2, #8
		MUL R3, R1, R2
		LDMFD SP!, {R1, R2}
		MOV PC, LR

        非叶子函数,可能会再次覆盖之前入栈的数据,那么就要在入栈的程序后,在下一个程序中紧跟着入栈。

        这段ARM汇编代码演示了如何在函数调用期间使用栈来保护现场和恢复现场,并且演示了如何嵌套调用多个函数。该代码使用STMFD和LDMFD指令将当前函数的寄存器值保存到栈中,并在函数返回时将这些值从栈中弹出,以恢复现场,具体的动态结果可以自行演示!

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

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

相关文章

(学习笔记-TCP基础知识)TCP与UDP区别

UDP UDP不提供复杂的控制机制,利用IP提供面向[无连接]的通信服务。 UDP协议非常简单,头部只有8个字节(位),UDP的头部格式如下: 目标和源端口:主要是告诉UDP协议应该把报文发给哪个进程包长度:该字段保存了…

【码银送书第二期】《高并发架构实战:从需求分析到系统设计》

很多软件工程师的职业规划是成为架构师,但是要成为架构师很多时候要求先有架构设计经验,而不做架构师又怎么会有架构设计经验呢?那么要如何获得架构设计经验呢? 一方面可以通过工作来学习,观察所在团队的架构师是如何…

栈和队列【数据结构】

1、栈 &#xff08;1&#xff09;Stack.h #pragma once #include <stdio.h> #include <assert.h> #include <stdlib.h> #include <stdbool.h>typedef int STDataType;typedef struct Stack {STDataType* a;int top;int capacity; }ST;void STInit(ST*…

设计模式——桥梁模式

桥梁模式 定义 桥梁模式&#xff08;Bridge Pattern&#xff09;也叫做桥接模式。 将抽象和显示解耦&#xff0c;使得两者可以独立地变化。 优缺点、应用场景 优点 抽象和实现的解耦。 这是桥梁模式的主要特点&#xff0c;它完全是为了解决继承的缺点而提出的设计模式。优…

声音生成项目(6)——在矢量量化变分编码器上使用自回归模型PixelCNN模型生成新的样本

文章目录 引言PixelCNN论文简读模型介绍自回归模型PixelCNN模型结构 基础知识回顾 代码实现PixelConvLayer具体运行过程卷积模块整体网络结构 模型执行效果问题解决训练好的模型在生成新的图片时&#xff0c;为什么要逐个元素进行生成&#xff1f;掩码卷积仅仅是考虑了一部分的…

R语言实现SMOTE与SMOGN算法解决不平衡数据的回归问题

本文介绍基于R语言中的UBL包&#xff0c;读取.csv格式的Excel表格文件&#xff0c;实现SMOTE算法与SMOGN算法&#xff0c;对机器学习、深度学习回归中&#xff0c;训练数据集不平衡的情况加以解决的具体方法。 在之前的文章Python实现SMOGN算法解决不平衡数据的回归问题&#x…

Spring初识(二)

前言 经过前面的学习,我们已经知道spring就是包含了众多方法的Ioc,那么既然是容器,就具备两个功能,我们接下来就是要介绍以下两个功能: 1.将对象存储到容器(spring)中: 2.从容器(spring)中将对象取出来. 这两个功能就应发出来,spring的创建和使用. 一.Spring创建 我们先来说…

Ubuntu关闭自动休眠

一、查看当前休眠模式 使用systemctl status sleep.target 命令查看当前休眠模式&#xff0c;结果如下图&#xff0c;sleep状态为enabled&#xff0c;表示自动休眠模式开启。 二、关闭自动休眠模式 使用sudo systemctl mask sleep.target suspend.target 关闭休眠模式 三…

面向初学者的卷积神经网络

卷积神经网络在机器学习中非常重要。如果你想做计算机视觉或图像识别任务&#xff0c;你根本离不开它们。但是很难理解它们是如何工作的。 在这篇文章中&#xff0c;我们将讨论卷积神经网络背后的机制、它的优点和应用领域。 什么是神经网络&#xff1f; 首先&#xff0c;让…

【ACM】—蓝桥杯大一暑期集训Day2

&#x1f680;欢迎来到本文&#x1f680; &#x1f349;个人简介&#xff1a;陈童学哦&#xff0c;目前正在学习C/C、Java、算法等方向&#xff0c;一个正在慢慢前行的普通人。 &#x1f3c0;系列专栏&#xff1a;陈童学的日记 &#x1f4a1;其他专栏&#xff1a;CSTL&#xff…

MySQL-分库分表详解(二)

♥️作者&#xff1a;小刘在C站 ♥️个人主页&#xff1a; 小刘主页 ♥️努力不一定有回报&#xff0c;但一定会有收获加油&#xff01;一起努力&#xff0c;共赴美好人生&#xff01; ♥️学习两年总结出的运维经验&#xff0c;以及思科模拟器全套网络实验教程。专栏&#xf…

Xcode报错--访问keychain,出现弹窗处理方案

情景 访问keychain弹出弹窗&#xff0c;不想人工点击&#xff0c;比如自动化测试中使用keychain中的证书的情况 原因 Mac的保护机制 处理 1、人工&#xff1a;输入Password&#xff0c;点击Allow或者Always Allow 2、命令行处理 security unlock-keychain -p "<…

Spring Batch之读数据库——JdbcCursorItemReader之自定义PreparedStatementSetter(三十八)

一、自定义PreparedStatementSetter 详情参考我的另一篇博客&#xff1a; Spring Batch之读数据库——JdbcCursorItemReader&#xff08;三十五&#xff09;_人……杰的博客-CSDN博客 二、项目实例 1.项目实例 2.代码实现 BatchMain.java&#xff1a; package com.xj.dem…

docker的安装以及常用命令详解

目录 一、docker简介 二、docker安装 三、常用命令 1、显示 Docker 版本信息 2、显示 Docker 系统信息&#xff0c;包括镜像和容器数 3、帮助 四、镜像管理 1、列出镜像 2、获取一个新的镜像 3、查找镜像 4、删除镜像 5、镜像导入与导出 五、容器生命周期 1、运行…

小程序form表单验证,validate 在更新数据以后不能验证?还是提示同样的错误

报错&#xff1a; 一直报手机号码必须填写&#xff0c;但是我已经填写了。 解决&#xff1a; 花了2个小时&#xff0c;最后发布是模式models写错了。 改完之后&#xff0c;终于提示别的错误了&#xff1a; 源码&#xff1a; //wxml <view class"welcome">欢…

安装Visual Studio Installer Projects 2022插件

VS主界面--扩展--管理扩展--搜索VS插件“Visual Studio Installer Projects 2022”并安装。

【多模态】1、几种多模态 vision-language 任务和数据集介绍

文章目录 一、Phrase Grounding1.1 概念介绍1.2 常用数据集介绍 二、Referring Expression Comprehension&#xff08;REC&#xff09;2.1 概念介绍2.2 常用数据集介绍 三、Visual Question Answer&#xff08;VQA&#xff09;3.1 概念介绍 四、Image Caption4.1 概念介绍 现在…

cookie 生命周期和cookie有效路径超级详细讲解

文章目录 cookie 生命周期和cookie有效路径超级详细讲解cookie 生命周期介绍代码示例完成测试 , 注意抓包看数据 cookie 有效路径有效路径规则规则如下:代码示例完成测试 , 注意抓包看创建 Cookie 时,返回的数据完成测试 , 注意抓包看读取 Cookie 时,返回的数据 代码示例html页…

bug:file name too long文件名超出系统最大限制

各操作系统支持最长的文件和目录名称长度&#xff08;Linux、Win、Mac&#xff09; 今天开发需求的时候发现无法新建文件&#xff0c;提示file name too lang&#xff0c;于是翻阅和查询了一些资料&#xff0c;发现不同操作系统下文件名和目录名最长的长度不同。 操作系统文件名…

elementUI 非表单格式的校验

在普通表单中对输入框、选择框都有校验案例。 但是在自定义非空中如何进行校验官网并没有说明 关键代码 clearValidate 方法清除校验 this.$refs.formValue.clearValidate(signinimg) 使用案例 <template><div class"stylebg"><Tabs icons"el-…