当前位置: 首页 > news >正文

81、【OS】【Nuttx】【启动】caller-saved 和 callee-saved 示例:压栈内容

【声明】本博客所有内容均为个人业余时间创作,所述技术案例均来自公开开源项目(如Github,Apache基金会),不涉及任何企业机密或未公开技术,如有侵权请联系删除

背景

接之前 blog
【OS】【Nuttx】【启动】caller-saved 和 callee-saved 示例:栈指针和帧指针(上)
【OS】【Nuttx】【启动】caller-saved 和 callee-saved 示例:栈指针和帧指针(下)
【OS】【Nuttx】【启动】caller-saved 和 callee-saved 示例:r7 寄存器
【OS】【Nuttx】【启动】caller-saved 和 callee-saved 示例:栈空间对齐
分析了栈指针和帧指针的一些概念,演示了栈帧的操作,解释了为什么选择 r7 寄存器作为帧指针,并分析了栈空间对齐,下面最后再补充点压栈内容细节

压栈内容

之前 blog 【OS】【Nuttx】【启动】caller-saved 和 callee-saved 示例:栈指针和帧指针(下) 分析了,参数寄存器只有 4 个,当输入参数超过 4 个时,需要将参数进行压栈
在这里插入图片描述
下面来看下参数超过 4 个的情况,代码如下

// main.c
static int add_func(int a, int b, int c, int d, int e) {return (a + b + c + d + e);
}int main(void) {int c = add_func(1, 2, 3, 4, 5);return 0;
}

终端 bash 中输入编译命令

arm-none-eabi-gcc -S -mcpu=cortex-m4 -mthumb main.c -o main.s

得到汇编文件 main.s

	.cpu cortex-m4.arch armv7e-m.fpu softvfp.eabi_attribute 20, 1.eabi_attribute 21, 1.eabi_attribute 23, 3.eabi_attribute 24, 1.eabi_attribute 25, 1.eabi_attribute 26, 1.eabi_attribute 30, 6.eabi_attribute 34, 1.eabi_attribute 18, 4.file	"main.c".text.align	1.syntax unified.thumb.thumb_func.type	add_func, %function
add_func:@ args = 4, pretend = 0, frame = 16@ frame_needed = 1, uses_anonymous_args = 0@ link register save eliminated.push	{r7}sub	sp, sp, #20add	r7, sp, #0str	r0, [r7, #12]str	r1, [r7, #8]str	r2, [r7, #4]str	r3, [r7]ldr	r2, [r7, #12]ldr	r3, [r7, #8]add	r2, r2, r3ldr	r3, [r7, #4]add	r2, r2, r3ldr	r3, [r7]add	r2, r2, r3ldr	r3, [r7, #24]add	r3, r3, r2mov	r0, r3adds	r7, r7, #20mov	sp, r7@ sp neededpop	{r7}bx	lr.size	add_func, .-add_func.align	1.global	main.syntax unified.thumb.thumb_func.type	main, %function
main:@ args = 0, pretend = 0, frame = 8@ frame_needed = 1, uses_anonymous_args = 0push	{r7, lr}sub	sp, sp, #16add	r7, sp, #8movs	r3, #5str	r3, [sp]movs	r3, #4movs	r2, #3movs	r1, #2movs	r0, #1bl	add_funcstr	r0, [r7, #4]movs	r3, #0mov	r0, r3adds	r7, r7, #8mov	sp, r7@ sp neededpop	{r7, pc}.size	main, .-main.ident	"GCC: (15:13.2.rel1-2) 13.2.1 20231009"

main

下面先来分析 main 函数
在这里插入图片描述

  • 56 行:将帧指针 r7 和返回地址 lr 进行压栈,保存好之前的上下文状态
    在这里插入图片描述
  • 57 行:sp 减去 16 字节,为 main 函数留出 16 字节的栈空间,注意,之前 add_func 只有 2 个输入参数的时候,sp 减去的是 8 字节,之所以这里多了 8 字节,是因为现在 add_func 有 5 个输入参数,其中 4 个参数由 R0-R3 参数寄存器保存,还剩下一个参数,需要保存到栈上
  • 这个多出来的参数是 int 类型,占 4 个字节,之前 blog 【OS】【Nuttx】【启动】caller-saved 和 callee-saved 示例:栈空间对齐 提到过,函数入口处,栈空间需要 8 字节对齐,而这个参数不属于 main 的栈空间,和 main 里面那些局部变量不属于一个系统,不能和栈空间里面的局部变量进行合并,所以这里单独占了 8 字节的入参进栈空间(caller-saved 原则),加上原先栈空间已对齐的 8 字节空间,所以是 8 + 8 = 16 字节空间
    在这里插入图片描述
  • 58 行:将帧指针 r7 加上 8 字节,这 8 字节属于 main 入参进栈保存的空间,不属于局部变量所属的栈空间,r7 帧指针不能操作读取
  • 59-60 行: 将多出来的一个入参保存到栈上
  • 61-64 行:剩下 4 个参数分别保存到 R0-R3 参数寄存器上
  • 65 行:跳转到 add_func

add_func

下面来看 add_func
在这里插入图片描述

  • 24 行:将帧指针 r7 压入栈中,之前 blog 【OS】【Nuttx】【启动】caller-saved 和 callee-saved 示例:叶子函数 有介绍过,为什么不把 lr 返回地址也压栈
    在这里插入图片描述

  • 25 行:为 add_func 申请 20 个字节的栈空间,用于存放局部变量,有 5 个 int 类型的入参,再加上前面压栈的 r7 寄存器,刚好 5 * 4 + 4 = 24 字节,已实现了 8 字节对齐
    在这里插入图片描述

  • 26 行:不需要额外申请 add_func 入参进栈空间,这里 sp 和 fp 相等

  • 27-30 行:将 R0-R3 参数寄存器的值保存到栈上空间

  • 31-37 行:将前 4 个入参进行相加

  • 38 行:将第 5 个入参从栈上取出,这里偏移 24 个字节,刚好到了 main 入参进栈的空间

  • 39-40 行:将第 5 个入参相加,结果保存到 R0 寄存器

至此,压栈内容分析完毕,后面继续开始栈溢出内容分析

http://www.xdnf.cn/news/1149067.html

相关文章:

  • Mybatis学习之简介(一)
  • Django接口自动化平台实现(三)
  • 多式联运物流管理系统的设计与实现(原创)
  • picoCTF 2024: [[NoSQL]] Injection - Writeup
  • 【MATLAB例程】Taylor算法用于TOA(到达时间)的三维标签位置解算,可自适应基站数量。附下载链接
  • 一个基于阿里云的C端Java服务的整体项目架构
  • 后缀树:字符串处理的利器
  • 模型轻量化全指南:从剪枝量化到低配置设备部署实战
  • 【Linux】基本指令详解(三) 指令本质、三个查找指令、打包压缩、重要热键、linux体系结构、命令行解释器
  • Go-Redis × 向量检索实战用 HNSW 在 Redis 中索引与查询文本 Embedding(Hash JSON 双版本)
  • 智能光电检测:YOLO+OpenCV联合算法工程实践
  • 【运维】flash attention安装出现错误及编译慢
  • 思维链(CoT)技术全景:原理、实现与前沿应用深度解析
  • windows wsl2-06-docker hello world
  • 1.初始化
  • Windows原生环境配置Claude Code MCP(通过JSON)
  • 【MySQL笔记】视图
  • Spring AI 项目实战(十九):Spring Boot + AI + Vue3 + OSS + DashScope 构建多模态视觉理解平台(附完整源码)
  • mac 配置svn
  • 医疗AI与融合数据库的整合:挑战、架构与未来展望(上)
  • xss-labs1-8题
  • 浏览器渲染原理——计算属性和布局过程常考内容
  • 基于单片机病床呼叫系统/床位呼叫系统
  • ChatGPT Agent深度解析:告别单纯问答,一个指令搞定复杂任务?
  • 目标检测中的标签分配算法总结
  • 2021 RoboCom 世界机器人开发者大赛-本科组(初赛)解题报告 | 珂学家
  • RS485转Profibus网关助力涡街液体流量计与300PLC高效通讯
  • Python高级数据类型:字典(Dictionary)
  • 模型的评估与选择
  • 基于springboot的考研互助小程序