qemu-ARM篇——ARM 栈帧(一)

news2024/11/25 21:25:26

ARM 栈帧

本系列均已 corter-A7(armv7-a) 为例

在 ARM 中,通常为满减栈(Full Descending FD), 也就是说,堆栈指针指向堆栈内存中最后一个填充的位置,并且随着每个新数据项被压入堆栈而递减。

栈的本质

要理解栈的本质,首先得明白,程序执行是怎么执行的?

程序执行其实就是对应一个又一个状态机,在 A 状态有对应的内核寄存器,在 B 状态也有对应的内核寄存器值。

A 状态切换到 B 状态,就需要把 A 状态的内核寄存器保存下来,不然无法从 B 状态再回到 A 状态。此时就需要将 A 状态下内核寄存器的值放到内存中,即入栈

B 状态切换到 A 状态,需要恢复 A 状态的现场,即内核寄存器的值,所以需要将存到内存中的数据写回到内核寄存器,即出栈

其实 linux/rtos 的任务也是一个又一个状态机,状态切换的时候,先将当前状态(A)的内核寄存器保存到内存中,再把下一个状态(B)的内核寄存器从内存中读回来,程序跳转到 B 状态执行,其实这就是上下文切换的过程。

入栈/出栈的本质其实就是内存中的一块区域进行操作:

  • 需要入栈的时候,就把内核寄存器的值写入到内存中
  • 需要出栈的时候,就把相应内存中的值写回到内核寄存器中

入栈

在这里插入图片描述
在调用入栈指令 PUSH/STMFD 之前,堆栈指针(SP)指向堆栈中最后一个被占用的字节,入栈指令完成后,堆栈指针被递减8(两个字),并且这两个字的内容被写入内存。

编号低的寄存器写入内存低地址处

出栈

假设要将:R0-R3 和 LR 寄存器入栈,当前的 SP 指针指向 0x80000000,由于 ARM 处理器的栈是向下增长的,使用的汇编代码如下:PUSH {R0-R3,LR}

入栈之后,内存分布如下
在这里插入图片描述

假设这个时候又对 LR 进行入栈操作,汇编代码如下:PUSH LR

入栈之后,内存分布如下

在这里插入图片描述
上面两个图就是分步对 R0-R3,R12,及 LR 进行压栈以后的编程模型,如果要出栈的话,就使用如下代码:

POP LR
POP {R0-R3,R12}

出栈的时候从栈顶开始,也就是 SP 当前执行的位置,地址依次增大,提取堆栈中的数据到要恢复的寄存器列表中。
PUSH 和 POP 的另一种写法是 STMFD SP! 和 LDMFD SP!
因此上面的代码可以写为

入栈
STMFD SP!,{R0~R3, R12}
STMFD SP! ,{LR}
出栈
LDMFD SP! ,{LR}
LDMFD SP! ,{R0~R3, R12}

示例测试

gdb 小技巧:

  • 窗口缩小:winheight src -5
  • 窗口放大:winheight src +5

入栈

入栈之前先查看当前寄存器
在这里插入图片描述

  • Info reg:从内核寄存器中可以看到,当前 r0 r1 r2 r3 lr 寄存器的值依次为:1 2 3 4 5
    sp 指针当前为0x801fffec

  • x/20 0x801fffec 查看 SP 栈指针地址数据
    在这里插入图片描述

可以看到 SP 地址数据从高到低依次为:5 4 3 2 1

从这里可以看到,编号低的寄存器写入内存低地址处

寄存器清零

在这里插入图片描述

出栈

在这里插入图片描述

源码

.global _start

_start:
    /* 进入 SVC 模式 */
    mrs r0, cpsr
    bic r0, r0, #0x1f /* 将  r0 寄存器中的低 5 位清零,也就是 cpsr 的 M0~M4 */
    orr r0, r0, #0x13 /* r0 或上 0x13,表示使用 SVC 模式 */
    msr cpsr, r0      /* 将 r0 的数据写入到 cpsr 中 */

    ldr sp, =0X80200000	/* 设置栈指针 */

    ldr r0, =0x01
    ldr r1, =0x02
    ldr r2, =0x03
    ldr r3, =0x04
    ldr lr, =0x05

    push {r0-r3, lr}
    /* nop for debug */
    nop
    nop
    nop

    mov r0, #0
    mov r1, #0
    mov r2, #0
    mov r3, #0
    mov lr, #0
    /* nop for debug */
    nop
    nop
    nop

    pop {r0-r3, lr}
    /* nop for debug */
    nop
    nop
    nop

    stmfd sp!, {r0-r3, lr}
    /* nop for debug */
    nop
    nop
    nop

    mov r0, #0
    mov r1, #0
    mov r2, #0
    mov r3, #0
    mov lr, #0
    /* nop for debug */
    nop
    nop
    nop

    ldmfd sp!, {r0-r3, lr}
    /* nop for debug */
    nop
    nop
    nop

loop:
    b loop

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

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

相关文章

前端CSS学习(三)

1、盒子模型 盒子的概念1、页面中的每一个标签,都可看做是一 个“盒子” ,通过盒子的视角更方便的进行布局2、浏览器在渲染 (显示)网页时,会将网页中的元素看做是一个个的矩形区域,我们也形象的称之为盒子CSS中规定每个盒子分别由…

BESV博世蔚发布2023全新款折叠e-bike —— F3,在中国自行车展会上大放异彩

BESV博世蔚身为跨界智慧出行的专家,今年在国内最大规模的中国国际自行车展上发布了其最新的e-bike折叠车款---VOTANI F3。拥有纯正荷兰血统的VOTANI系列车款,在设计外观上沿袭了欧风的极简主义和时尚设计,并搭配上折叠系统更易于携带和收纳。…

AnyStock JS Crack,AnyStock JS功能

AnyStock JS Crack,AnyStock JS功能 添加了新的技术指标-除了已经支持的几十个指标外,股票图表现在还提供了三个新的开箱即用技术指标: Aroon振荡器-通过从Aroon Up中减去Aroon Down,可以很容易地测量趋势的强度。 加权移动平均线(WMA)-通过更…

D-遗迹探险

牛客小白月赛 72 D 题目链接 链接:https://ac.nowcoder.com/acm/contest/56825/D 来源:牛客网 示例1 输入 3 3 1 2 3 4 5 6 7 8 9 2 2 1 1 3 3 3 1 1 1 3 3 1输出 58 41题解: 如果先不考虑传送门,这题就是一道简单dp 设状态 …

【后端随笔】mysql操作语句记录

sql语句不区分大小写 show bases; --号注释 /**/多行注释 DDL定义 DML删改 DQL查询 DCL权限控制语言 1、DDL操作数据库 (1)查询 SHOW DATABASES; (2)创建 CREATE DATABASES;//创建数据库 CREATE DATABASES IF NOT EXISTS 数据库名称&#xff…

stata学习笔记①stata基础介绍

文章目录 一、为什么要学stata二、软件基本解释1.软件界面2.导入示例数据3.认识几个重要的功能符号 三、数据的基本观测四、统计性描述1.codebook 数据字典使用2.summarize 五、图像初步探索1.histogram 直方图2.graph box /hbox 箱线图3.vioplot小提琴图 一、为什么要学stata …

JavaWeb:过滤器 Filter、监听器 Listener

文章目录 JavaWeb - 04一、Filter1. 概述2. 实现步骤3. 运行结果 二、Filter 应用:实现权限拦截1. 登录步骤2. 添加的过滤器部分3. 运行结果4. 总结 三、监听器注意: JavaWeb - 04 一、Filter 1. 概述 Filter:过滤器,可以用来过…

有用的知识又增加了:为何无法编译某些  WWDC 官方视频中的代码?

概览 作为 Apple 开发者而言,每期 WWDC 官方视频无疑是我们日常必看的内容。 不过,小伙伴们是否发现视频中有些示例代码在我们自己测试时却无法编译这一尴尬的情况呢? 在本篇博文中,我们将通过一则非常简单的示例来向大家展示为…

【Matlab】基于遗传算法的列车发车时刻(发车间隔)优化

【Matlab】基于遗传算法的列车发车时刻(发车间隔)优化 一、模型介绍(一)引言(二)符号定义(三)目标函数(四)约束条件4.1到达乘客数量4.2乘客进站限制4.3乘客总数量&#x…

Kyligence Zen产品体验-从人找数据到数据找人

目录 前言: 一、什么是Kyligence Zen? 1、个人总结 2、官方简介 二、1分钟打开新世界大门 个人总结: 1、注册 2、验证登录 三、上手初体验 1、快速上手(入门) 2、定制化应用 四、实战体验 综述: 1、卡…

java transient关键字 JSON序列化问题

今天做项目的时候,遇到了一个奇怪的事情看图: 在这个JSONObject中是有这个object对象的,但是我输出的的却没有这个对象,这是怎么回事? 这样不明显我换一个方式去输出 我在查看了代码之后发现了我的ResponseStatus这…

数据结构-查找-树形结构(二叉排序树、二叉平衡树、红黑树、B树、B+树)查找

目录 一、二叉排序树(BST) 查询 插入 构造二叉排序树 *删除 *查找效率分析 二、二叉平衡树 *插入数据保持平衡 LL ​编辑 RR LR RL 结 *查找效率分析 删除 三、红黑树 *插入 *删除 四、B树 *插入 *删除 五、B树 一、二叉排序树(BST) 定义:二叉排序…

python的opencv操作记录(13)-增强之直方图均衡化

文章目录 直方图增强基本逻辑-均衡化calcHist && equalizeHistcalcHistequalizeHist 自适应直方图均衡化 前段时间忙活深度网络和android的东西去了,好久没讲讲传统图像处理了,这一篇继续来说说opencv中的传统图像处理部分——图像增强之直方图增…

【谷粒商城之订单服务-RabbitMQ延时队列】

本笔记内容为尚硅谷谷粒商城订单服务锁库存事务最终一致性部分 目录 一、RabbitMQ延时队列 二、具体实现 1、 创建上述队列和路由组件 2、解锁库存 解锁库存的两种情况 1、当订单业务提交后回滚 2、订单取消解锁库存 三、关闭订单 四、消息丢失、挤压、重复等解决方案…

c++ 继承与派生

继承就是在原有类的基础上产生新类,从而减少了代码重复的必要 格式: class A{}; class B:继承方式 A{}; 在c继承中,有以下几点注意 (1)基类的构造函数与析构函数不能被继承 (2)派生类对基类成员的继承没有选择权,不能选择继承…

c++ 常用总结(三)

1.设计模式 GitHub - FengJungle/DesignPattern: Design pattern demo code (一) ① 简单工厂模式 再不学简单工厂模式,就真的要去工厂搬砖啦~_冯Jungle的博客-CSDN博客 通过以下的例子可见,只需要提供产品名称作为参数&…

基于springboot+mysql+SpringDataJPA +html实现学生选课管理系统

基于springbootmysqlSpringDataJPA html实现学生选课管理系统 一、系统介绍1、系统主要功能:2.涉及技术框架:3.本项目所用环境:4.项目需求 二、功能展示三、其它系统四、获取源码 一、系统介绍 1、系统主要功能: 管理员&#xf…

【C++】| 03——STL | 迭代器

系列文章目录 【C】| 01——泛型编程 | 模板 【C】| 02——STL | 初识 【C】| 03——STL | 迭代器 【C】| 04——STL | 容器_vector 文章目录 1. 什么是迭代器2. 迭代器的分类3. 不同容器对应的迭代器4. 迭代器的好处5. 迭代器的操作 1. 什么是迭代器 迭代器就是指向容器内元素…

基于MATLAB的路面裂缝检测识别算法代码(GUI系统设计+图像预处理+裂缝检测)

资源地址: 基于MATLAB的路面裂缝检测识别算法代码(GUI系统设计图像预处理裂缝检测)资源-CSDN文库 主要内容: 1、运行Gui_Main.m程序,得到GUI界面 2、首先点击载入图像文件 3、后续便可以点击右侧的其他按钮进行分析…