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

ARMV8 - A64 - 函数调用,内存栈操作

说明

  • 看了下ARM平台上C语言函数调用的反汇编代码,理清楚了其中的内存栈汇编操作,特整理下。
  • 本文环境基于:ARMv8-a架构A53核soc,aarch64状态。

预先了解的知识点

内存栈

  • 栈和栈帧的基本概念
  • 重点:出栈入栈的单位不是单个局部变量,而是栈帧。

相关寄存器

  1. FP:Frame Pointer(栈帧指针),指向当前栈帧的顶部,在A53平台是使用通用寄存器x29保存。
  2. SP:Stack Pointer(栈顶指针),保存当前栈顶地址,在A53平台是一个特殊寄存器,不同异常等级是不同的寄存器,
  3. LR:Link Register(链接寄存器),保存子函数运行结束后的返回地址(跳转指令的下一条指令地址),在A53平台是使用通用寄存器x30充当,详细使用请看bl和ret指令说明。
  • 问题:初次了解,不好理解和区分FP和SP的作用和角色,SP是全局唯一的保存栈顶地址的寄存器,而FP是保存单个函数的栈帧基址,调用新函数,入栈操作结束后,需要将SP的值赋值给FP,类似于:SP是全局变量,而x29是局部变量,虽然大部分时刻两个寄存器值是一样的。

相关汇编指令

  • 函数调用实现原理,跳转和返回指令
  • 内存操作store,load

实例

  • C源码(a.c)
#include <stdio.h>int test1()
{return test(1, 2);
}int test(int a, int b)
{return a+b;
}int main()
{test1();return 0;
}
  • 对应的汇编代码(aarch64-linux-gnu-gcc -S a.c)
    .arch armv8-a.file   "a.c".text.align  2.global test1.type   test1, %function
test1:stp x29, x30, [sp, -16]!add x29, sp, 0mov w1, 2mov w0, 1bl  testldp x29, x30, [sp], 16ret.size   test1, .-test1.align  2.global test.type   test, %function
test:sub sp, sp, #16str w0, [sp, 12]str w1, [sp, 8]ldr w1, [sp, 12]ldr w0, [sp, 8]add w0, w1, w0add sp, sp, 16ret.size   test, .-test.align  2.global main.type   main, %function
main:stp x29, x30, [sp, -16]!add x29, sp, 0bl  test1mov w0, 0ldp x29, x30, [sp], 16ret.size   main, .-main.ident  "GCC: (Linaro GCC 6.3-2017.05) 6.3.1 20170404".section    .note.GNU-stack,"",@progbits

说明

  • 从汇编代码可以看出存在两种不同实现,如下:
  1. 函数调用栈中间函数(test1)
  2. 函数调用栈末端函数(test)

中间函数

test1:stp x29, x30, [sp, -16]! //将栈空间扩大16字节(更改sp寄存器值),再将x29,x30的数据(遗传自父函数)保存到栈顶 add x29, sp, 0 //将栈顶地址(sp)即此函数的栈帧基址保存到x29,...  //函数操作(省略)bl  test //跳转到test函数执行ldp x29, x30, [sp], 16 //将栈顶数据load到x29,x30中,再缩小栈空间16字节(即将sp恢复到父函数的栈顶)ret //返回父函数

末端函数

test:sub sp, sp, #16 //将sp保存的数据减小16字节,即将栈空间扩大16字节... //函数操作(省略)add sp, sp, 16 //将sp保存的数据增加16字节,即将栈空间缩小16字节ret

问题

  1. 为什么中间函数和末端函数实现不同,中间函数需要将x29,x30保存到栈内存中,最后再从栈内存中load到x29,x30中。
  • 是因为中间函数(test1)bl指令调用末端函数(test)时,会覆盖掉x30的数据(原本保存的是父函数main,跳转test1的下一条指令),覆盖后中间函数(test1)的ret指令就跳不回main函数了,因此需要先将x30的数据保存到栈上,从子函数跳转回来后,需要将x29,x30的数据从栈上恢复。
  • x29是栈帧指针,保存是当前函数的frame pointer,是约定俗成,因此需要保存和恢复,但是也不是必须,例如:test函数中就没有使用x29。

注意项

  1. sp 必须16Byte 对齐,扩大和缩小都必须是16字节的倍数。

相关文章:

ARMV8 - A64 - 函数调用,内存栈操作

说明 看了下ARM平台上C语言函数调用的反汇编代码&#xff0c;理清楚了其中的内存栈汇编操作&#xff0c;特整理下。本文环境基于&#xff1a;ARMv8-a架构A53核soc&#xff0c;aarch64状态。 预先了解的知识点 内存栈 栈和栈帧的基本概念重点&#xff1a;出栈入栈的单位不是…...

MyBatis 四大核心组件之 ResultSetHandler 源码解析

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f4ab; GitCode &#x1f496; 欢迎点赞…...

docker-compose 单机容器编排

docker-compose 单机容器编排 Dockerfile&#xff1a;先配置好的文件&#xff0c;然后bulid&#xff0c;镜像容器。 docker-compose 既可以基于dockerfile&#xff0c;也可以基于镜像&#xff0c;一键式拉起镜像和容器。 docker-compose 核心就是yml文件&#xff0c;可以定义…...

springboot项目使用Layui作为前端UI的一系列前后端交互的解决方法

背景&#xff1a; 因为比较喜欢Layui&#xff0c;因为多个项目都是从零开始就使用的layui开发的&#xff0c;并且开发过程中借鉴了很多其他项目&#xff08;如Ruoyi、Pear Admin&#xff09;&#xff0c;因此最终选用大部分Pear Admin的项目中使用的一系列解决方案&#xff0c;…...

【Linux】Firewalld防火墙新增端口、开启、查看等

Linux操作系统中&#xff0c;Firewalld防火墙相关操作如下&#xff1a; 安装 yum install firewalld firewalld-configFirewall开启常见端口命令 新增端口&#xff1a; firewall-cmd --zonepublic --add-port80/tcp --permanentfirewall-cmd --zonepublic --add-port443/tc…...

学习笔记 -- TVS管选型参考

一、TVS管基本工作原理 当TVS管(瞬态电压抑制器)两极受到反向瞬态高能量冲击时&#xff0c;能以纳秒(ns)量级的速度&#xff0c;将两极间的高阻抗变为低阻抗&#xff0c;使两极间的电压箝位于一个预定的值&#xff0c;有效地保护电子线路中的元器件。 在浪涌电压作用下&#xf…...

功能更新|免费敏捷工具Leangoo领歌私有部署新增第三方身份认证和API对接

Leangoo领歌是一款永久免费的专业的敏捷开发管理工具&#xff0c;提供端到端敏捷研发管理解决方案&#xff0c;涵盖敏捷需求管理、任务协同、进展跟踪、统计度量等。 Leangoo支持敏捷研发管理全流程&#xff0c;包括小型团队敏捷开发&#xff0c;规模化敏捷SAFe&#xff0c;Scr…...

重生奇迹mu战士加点

在重生奇迹MU中&#xff0c;战士作为一个近战职业&#xff0c;主要依赖于物理攻击来输出伤害。因此&#xff0c;在加点方面&#xff0c;战士需要优先考虑加强自身的攻击力&#xff0c;同时也要增强自身的生存能力和耐久度。 以下是可参考的战士加点方案&#xff1a; 1.力量&a…...

【数据结构(十一·多路查找树)】B树、B+树、B*树(6)

文章目录 1. 二叉树 与 B树1.1. 二叉树存在的问题1.2. 多叉树 的概念1.3. B树 的基本介绍 2. 多叉树——2-3树2.1. 基本概念2.2. 实例应用2.3. 其他说明 3. B 树、B树 和 B*树3.1. B树 的介绍3.2. B树 的介绍3.2. B*树 的介绍 1. 二叉树 与 B树 1.1. 二叉树存在的问题 二叉树…...

弟弟的作业

问题 G: 弟弟的作业 [命题人 : 外部导入] 时间限制 : 1.000 sec 内存限制 : 128 MB 题目描述 你的弟弟刚做完了“100以内数的加减法”这部分的作业&#xff0c;请你帮他检查一下。每道题目&#xff08;包括弟弟的答案&#xff09;的格式为abc或者a-bc&#xff0c;其中a和b是作…...

代码随想录算法训练营第37天|● 738.单调递增的数字 ● 968.监控二叉树 ● 总结

738. 单调递增的数字 中等 相关标签 相关企业 提示 当且仅当每个相邻位数上的数字 x 和 y 满足 x < y 时&#xff0c;我们称这个整数是单调递增的。 给定一个整数 n &#xff0c;返回 小于或等于 n 的最大数字&#xff0c;且数字呈 单调递增 。 示例 1: 输入: n 10输出: …...

出现 java: 找不到符号 符号: 变量 log 的解决方法

目录 1. 问题所示2. 原理分析3. 解决方法3.1 增加编译参数3.2 增加lombok插件3.3 清楚本地缓存1. 问题所示 使用Springboot启动项目的时候,出现如下bug: java: 找不到符号符号: 变量 log位置: 类 org.springblade.example.consumer.rpc.BlogStu...

大数据机器学习与深度学习—— 生成对抗网络(GAN)

GAN概述 在讲GAN之前&#xff0c;先讲一个小趣事&#xff0c;你知道GAN是怎么被发明的吗&#xff1f;据Ian Goodfellow自己说&#xff1a; 之前他一直在研究生成模型&#xff0c;可能是一时兴起&#xff0c;有一天他在酒吧喝酒时&#xff0c;在酒吧里跟朋友讨论起生成模型。然…...

vue前端访问Django channels WebSocket失败

现象 前端报错&#xff1a;SSH.vue:51 WebSocket connection to ‘ws://127.0.0.1:8000/server/terminal/120.59.88.26/22/1/’ failed: 后端报错&#xff1a;Not Found: /server/terminal/120.79.83.26/22/1/ 原因 django的版本与channels的版本不匹配&#xff08;django…...

厉害了!水浸监控技术有升级啦

水浸监控在今天的社会中变得愈发重要&#xff0c;特别是在各种行业和场所。面对突发的水灾&#xff0c;及时有效的监测和预警系统可以帮助组织减少损失&#xff0c;保障人员和财产的安全。 客户案例 商业办公楼 合肥某大型商业办公楼面临着水灾风险&#xff0c;而传统的监控系…...

【开题报告】基于SpringBoot的大学生心理教育平台的设计与实现

1.研究背景 大学生心理健康问题一直备受关注。随着社会压力的增加、人际关系的复杂化以及学业与就业压力等因素的影响&#xff0c;大学生心理健康问题日益突出。因此&#xff0c;设计并实现基于SpringBoot的大学生心理教育平台具有重要的研究意义和实践价值。 &#xff08;1&…...

376. 摆动序列

376. 摆动序列 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;参考代码&#xff1a;_376摆动序列_376摆动序列 错误经验吸取 原题链接&#xff1a; 376. 摆动序列 https://leetcode.cn/problems/wiggle-subsequence/description/ 完成情况&#xff1a; 解题…...

现在个人想上架微信小游戏已经这么难了吗...

引言 大家好&#xff0c;最近我突然想起来我还有一款微信小游戏还没有上架&#xff0c;于是捣鼓了一天把游戏完善了一下&#xff0c;然后准备提交审核&#xff0c;却发现异常的艰难... 1.为什么难&#xff1f; 相信大家都大概知道&#xff0c;自从微信平台宣布 9月1日起&…...

C语言数据结构-----二叉树(2)堆的深入理解及应用、链式二叉树的讲解及代码实现

前言 本篇文章讲述的内容有部分是上一节写过的。重复内容不会再进行说明&#xff0c;大家可以看上一节内容 链接: C语言数据结构-----二叉树(1)认识数、二叉树、堆及堆的代码实现 文章目录 前言1.使用堆解决TOP-K问题2.向下调整堆的时间复杂度与向上调整堆的时间复杂度对比3.堆…...

【算法】【动规】等差数列划分

跳转汇总链接 &#x1f449;&#x1f517;算法题汇总链接 1.2 等差数列划分 &#x1f517;题目链接 如果一个数列 至少有三个元素 &#xff0c;并且任意两个相邻元素之差相同&#xff0c;则称该数列为等差数列。例如&#xff0c;[1,3,5,7,9]、[7,7,7,7] 和 [3,-1,-5,-9] 都是…...

用Python+Simulink复现数维杯A题:手把手教你搭建车辆主动减振模型(附代码)

PythonSimulink实战&#xff1a;从零构建车辆主动减振系统 1. 理解车辆振动控制的核心问题 车辆振动问题一直是工程领域的重要挑战。想象一下&#xff0c;当你驾驶一辆重型卡车经过颠簸路面时&#xff0c;那种令人不适的震动不仅影响驾驶体验&#xff0c;长期来看还会对车辆结构…...

敏捷团队沟通技巧:减少冲突的5个方法

在敏捷开发环境中&#xff0c;软件测试从业者常面临跨职能冲突的挑战。数据显示&#xff0c;超过70%的项目延迟源于沟通不畅&#xff0c;尤其在测试与开发团队之间&#xff0c;角色目标错位&#xff08;如开发侧重快速交付&#xff0c;测试聚焦风险防控&#xff09;易引发摩擦。…...

警惕!新型U盘蠕虫伪装文档传播:实测火绒5.0查杀+防御全攻略

深度解析U盘蠕虫病毒&#xff1a;从防御到查杀的全面安全指南 1. 新型U盘蠕虫病毒的运作机制剖析 U盘蠕虫病毒近年来呈现出越来越复杂的传播方式和技术手段。这类病毒通常利用Windows系统的自动播放功能&#xff08;AutoRun.inf&#xff09;或注册表劫持技术进行传播&#xff0…...

n600高效涡流选粉机设计【说明书 CAD图纸 开题报告 任务书 实习报告】

n600高效涡流选粉机作为粉体分级领域的核心设备&#xff0c;其设计聚焦于提升分级精度与处理效率。该设备通过优化涡流场分布与颗粒运动轨迹&#xff0c;实现微细粉体的高效分离。其核心作用在于利用离心力和气流的复合作用&#xff0c;使不同粒径的颗粒在旋转流场中产生差异化…...

Qwen3-TTS开源大模型效果展示:俄文/葡萄牙文/意大利文等小语种高自然度语音生成

Qwen3-TTS开源大模型效果展示&#xff1a;俄文/葡萄牙文/意大利文等小语种高自然度语音生成 你听过AI用俄语讲普希金的诗吗&#xff1f;或者用意大利语念一段歌剧台词&#xff1f;过去&#xff0c;想让AI生成地道的小语种语音&#xff0c;要么音色机械&#xff0c;要么口音奇怪…...

FlowState Lab结合计算机网络概念:模拟智能网络配置助手

FlowState Lab结合计算机网络概念&#xff1a;模拟智能网络配置助手 1. 网络运维的痛点与AI解决方案 网络工程师每天都要面对复杂的网络环境和层出不穷的故障问题。传统排错流程往往需要工程师手动检查设备配置、分析日志信息、查阅技术文档&#xff0c;这个过程耗时耗力且容…...

深入解析GNSS信号跟踪环路:从PLL/DLL原理到Python仿真实践

1. GNSS信号跟踪环路基础概念 当你用手机导航时&#xff0c;背后其实藏着一套精密的信号追踪系统。想象一下&#xff0c;头顶的GPS卫星就像演唱会上的歌手&#xff0c;而你的手机接收机则是要听清歌词的观众。但现实中存在两个主要干扰&#xff1a;一是你和歌手都在移动&#x…...

告别卡顿!用MobileNetv2+MPPTSNet-EC在树莓派上跑实时语义分割(附完整配置与性能测试)

树莓派实战&#xff1a;MobileNetv2MPPTSNet-EC实时语义分割全流程解析 当你在树莓派上第一次看到摄像头画面被实时分割成不同语义区域时&#xff0c;那种成就感绝对值得记录。本文将带你完整实现从模型选择到部署优化的全流程&#xff0c;用MobileNetv2MPPTSNet-EC这套组合拳&…...

VMware Workstation 16开机自启踩坑实录:从环境变量报错到bat脚本优化,一篇搞定

VMware Workstation 16开机自启全攻略&#xff1a;从环境变量到脚本优化的深度实践 每次重启服务器后手动打开虚拟机实在是个体力活。上周我负责维护的测试环境又因为忘记启动虚拟机导致整个团队阻塞了半天&#xff0c;这种低级错误让我决定彻底解决VMware Workstation的开机自…...

好用还专业!AI智能降重工具深度测评与推荐

2026年真正好用的AI论文降重与改写工具&#xff0c;核心看降重效果、去AI味、格式保留、学术适配四大指标。综合实测&#xff0c;千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队&#xff0c;覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 …...