深入理解函数调用过程以及函数栈的变化

pve系统安装和配置 修改set compatible 为 set nocompatible,并在下一行添加set backspace=2。pve 8.2.2 是基于 debian 12 系统的,他们本地的源有点问题不能下载软件。 阅读详情

前言:
函数在编程中的重要性不言而喻。函数三要素,函数参数以及局部变量存在于栈上,局部变量定义需要初始化等,这些所谓的函数特征都熟背于心,时刻指导着我们设计函数。但这背后的原理是什么呢?底层的技术又是怎么实现?接下来将解开函数调用的神秘面纱!

1 栈帧(Stack Frame)
从逻辑上讲,栈帧就是一个函数执行的环境:函数参数、函数的局部变量、函数返回地址。每个函数的每次调用,都有它自己独立的一个栈帧,这个栈帧中维持着所需要的各种信息。这里也说明了只含有局部变量(无全局或静态变量)的函数,是可重入的,因为每次调用的栈帧是独立的。
在ARM处理器中,寄存器R11(fp)指向当前的栈帧的底部(高地址),寄存器R13(sp)指向当前的栈帧的顶部(低地址)。

2 ARM指令集(Instruction-Set)
汇编指令,粗略看来有两种,分别用于CPU内部的寄存器之间的数据传递以及寄存器和CPU外部的内存之间的数据传递,前者速度快于后者。
也就是说,CPU处理数据的来源是寄存器,而寄存器的数据来源可以是寄存器,也可以是内存。也就有了不同的汇编指令:

寄存器之间的数据传递(部分指令截取):
在这里插入图片描述

寄存器和内存之间的数据传递:
STR(store register to a virtual address in memory):将寄存器中的数据存储到内存中
LDR(load a single value from a virtual address in memory):将内存中的数据存储至寄存器

3 函数调用过程的汇编代码分析
有了前面1,2节的理解,就可以着手分析函数的汇编代码。

双目视觉入门实战:用Matlab标定相机,再到Python OpenCV完成测距的完整链路 本文详细介绍了双目视觉技术的完整实现流程,从Matlab相机标定到Python OpenCV测距的全链路实践。重点解析了Matlab与OpenCV的参数转换技巧,以及立体校正、视差计算等关键步骤的代码实现,帮助开发者快速掌握双目测距系统的搭建方法。 阅读详情

相关推荐

函数调用是如何变化的?

大家都知道函数调用是通过来实现的,而且知道在中存放着该函数的局部变量。但是对于的实现细节可能不一定清楚。本文将介绍一下在Linux平台下函数是如何实现的。的结构 函数在调用的时...

编程与实战的博客 3475

函数调用过程变化

进程内存区域 当进程被加载到内存时,会被分成很多段 代码段:保存程序文本,指令指针EIP就是指向代码段,可读可执行不可写,如果发生写操作则会提示segmentation fault 数据段:保存初始化的全局变量和静态变量,可读可写不可执行 BSS:未初始化的全局变量和静态变量 堆(Heap):动态分配内存,向地址增大的方向增长,可读可写可执行 (Stack):存放局部变量,函数参数,当前状态,函数调用信息等,向地址减小的方向增长,可读可写可执行 环境/参数段(environment/argumentss

weixin_43405004的博客 1651

joi_240913_8.8.0_73327_share-2EM46K.apk

joi_240913_8.8.0_73327_share-2EM46K.apk

函数调用过程空间的变化

友链 参考链接: 这个ppt真心不赖 备份连接 第二部分: 我们首先要明白,在内存中,只是一个概念,它并不是实实在在存在的东西 他是由ss、ebp和esp这三个寄存器定义出来的 ss段寄存器定义了所谓的在内存中的范围,即起始地址至终止地址 在这个内存范围内,我们可以定义自己的空间 在内存中,的增长方向通常为向低地址生长 那么ebp和esp寄存器就分别指向了的底部(高地址)和的顶部(低地址) 每次push都会导致esp变得更小,每次pop都会让esp变得更大 那么到了这里,我们对就有

ma_de_hao_mei_le的博客 997

函数调用 剖析+图解

: 在函数调用时,第一个进的是主函数函数调用后的下一条指令函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入的,然后是函数中的局部变量。注意静态变量是不入的。 当本次函数调用结束后,局部变量先出,然后是参数,最后顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。 当发生函数调用的时候,

wangyezi19930928的专栏 5万+

C语言函数调用时候内存中的动态变化详细分析

先了解如下几点知识和过程: *冯诺伊曼体系计算机程序指令代码都是提前从硬盘加载进入内存从而执行的(如果是哈佛体系结构的计算机指令代码是直接在外存里面执行的,具体可以看我这篇文章,计算机冯诺伊曼体系结构和哈佛体系结构区别和处理器性能评判标准),这些指令代码是存放在内存中进程的代码段,同一个函数内的指令代码是按照地址顺序存储的(编译器决定的)(也就是说只要指令地址+1就可以自动得到下一条指令的地址...

biao2488890051的博客 1万+

函数调用过程变化

转载自:https://blog.csdn.net/xbb224007/article/details/80106961 前言:本文旨在从汇编代码的角度出发,分析函数调用过程变化的简单介绍: 当某个函数运行时,机器需要分配一定的内存去进行函数内的各种操作,这个过程中分配的那部分称为。下图描述了的通用结构。是一段有界限的内存区间,由最顶端的两个指针界定,寄存器%ebp为指针,而寄存器%esp为指针(也就是说寄存器%ebp保存了所分配内存的最高地址,寄存器...

Liumotor的博客 962

什么是

浅析 什么是 引用百度百科中的解释: 也叫过程活动记录,是编译器用来实现过程/函数调用的一种数据结构。 函数的每次调用,都有它自己独立的中维持着函数调用所需要的各种信息,包括函数的入参、函数的局部变量、函数执行完成后应该返回到哪里等。 运行时 使用了这一数据结构,达到了后进先出(First In Last Out)的内存管理原则。不管是插入数据还是删除数据,都是在顶进行的。 x86-64的由高地址向低地址增长,寄存器rbp指向当前的底部(高地址),寄存器rsp指向当前

Respiration 1万+

c语言中staloc是什么意思,C语言函数调用(三)

6 调用实例分析本节通过代码实例分析函数调用过程的布局、形成和消亡。6.1 的布局示例代码如下://StackReg.c#include //获取函数运行时寄存器%ebp和%esp的值#define FETCH_SREG(_ebp, _esp) do{\asm volatile( \"movl %%ebp, %0 \n" \"movl %%esp, %1 \n" \: "=r"...

weixin_34486033的博客 517

【C】内功心法——函数

✨博客主页:心辛向荣 ✨系列专栏:【从0到1,C语言学习】 ✨一句短话:你若盛开,蝴蝶自来! ✨博客说明:尽己所能,把每一篇博客写好,帮助自己熟悉所学知识,也希望自己的这些内容可以帮助到一些在学习路上的伙伴,文章中如果发现错误及不足之处,还望在评论区留言,我们一起交流进步!😊 💻前言 🍁这篇博客解析函数,理解函数的创建与销毁的过程,可以从底层上理解一些知识点,做到知其然,知其所以然。 🍁理解好函数可以让我们所学的知识不只是停留在表面,同时可以更好的理解现在及以后所学到的知识,所以这是在..

trong_ 的烂笔头 1022

函数调用过程函数详解

当进程被加载到内存时,会被分成很多段 代码段:保存程序文本,指令指针EIP就是指向代码段,可读可执行不可写,如果发生写操作则会提示segmentation fault 数据段:保存初始化的全局变量和静态变量,可读可写不可执行 BSS:未初始化的全局变量和静态变量 堆(Heap):动态分配内存,向地址增大的方向增长,可读可写可执行 (Stack):存放局部变量,函数参数,当前状...

u012218309的博客 3万+

函数调用过程(图解)

图解函数调用变化过程

m0_63101588的博客 3385

函数调用过程中的结构及其变化

前言:本文旨在从汇编代码的角度出发,分析函数调用过程变化的简单介绍: 当某个函数运行时,机器需要分配一定的内存去进行函数内的各种操作,这个过程中分配的那部分称为。下图描述了的通用结构。是一段有界限的内存区间,由最顶端的两个指针界定,寄存器%ebp为指针,而寄存器%esp为指针(也就是说寄存器%ebp保存了所分配内存的最高地址,寄存器%esp保存...

7TribeZ的博客 1311

程序员应了解的那些事(28) 函数调用过程中的结构及其变化

前言:本文旨在从汇编代码的角度出发,分析函数调用过程变化。※的简单介绍: 当某个函数运行时,机器需要分配一定的内存去进行函数内的各种操作,这个过程中分配的那部分称为。下图描述了的通用结构。是一段有界限的内存区间,由最顶端的两个指针界定,寄存器%ebp为基址指针寄存器(extended base pointer),而寄存器%esp为指针寄存器(extended stack pointer)(也就是说寄存器%ebp保存了所分配内存的最高地址,寄存器%esp保存了所分配内...

qfturauyls的博客 1322

的基础知识-函数调用过程图解

的基础知识 eip寄存器 存放的指针指向程序即将执行到的地址 esp(32位)/rsp(64位)寄存器 存放函数顶指针 ebp/rbp寄存器 存放函数底指针 函数调用 过程函数调用是指程序运行时内存一段连续的区域 •用来保存函数运行时的状态信息,包括函数参数与局部变量等 •称之为“”是因为发生函数调用时,调用函数(caller)的状态被保存在内,被调用函数(callee)的状态被压入调用顶 •在函数调用结束时,顶的函数(callee)状态被弹出,顶恢复到调用函数(caller

qq_40410406的博客 1万+

C语言在函数调用时,是如何变化的?

为什么会写篇变化的文章?做系统分析的话你肯定遇到过一些crash, oops等棘手问题,一般大家都会用 gdb, objdump 或者 addr2line等工具分析 pc 位置来定位出错的地方。但是这些分析工具背后的本质原理就不见得理解深刻了,而且有的时候面对一系列 backtrace 或者 stack 日志处于懵逼的状态。 今天和大家一起看下面对 crash 日志的时候,如何利用 stack 来分析其变化的来龙去脉。 Arm指令集介绍 崇尚简单粗暴的介绍方式,我们直接来看各个寄存器...

LETFLY'S LAB 2026

【图文】函数调用过程变化

大家都知道函数调用是通过来实现的,而且知道在中存放着该函数的局部变量。但是对于的实现细节可能不一定清楚。本文将介绍一下在Linux平台下函数是如何实现的。 的结构 函数在调用的时候都是在空间上开辟一段空间以供函数使用,所以,我们先来了解一下通用的结构。 如图所示,是由高地址向地地址的方向生长的,而且有其顶和底,入的地方就叫做顶。 在x86系统的CPU中,rsp是指针寄存器,这个寄存器中存储着顶的地址。 rbp中存储着底的地址。 函数空间主要是由这两个寄存器来确定的

嵌入式与Linux那些事的博客 2438

溢出逆向实验

溢出逆向实验 一、实验背景 1.内存的不同用途 缓冲区溢出是在大缓冲区中的数据向小缓冲区复制的过程中,由于没有注意小缓冲区的边界,“撑爆”了较小的缓冲区,从而冲掉了和小缓冲区相邻内存区域的其他数据而引起的内存问题。缓冲溢出是最常见的内存错误之一,也是攻击者入侵系统时所用到的最强大、最经典的一类漏洞利用方式。成功地利用缓冲区溢出漏洞可以修改内存中变量的值,甚至可以劫持进程,执行恶意代码,最终获得主机的控制权。要透彻地理解这种攻击方式,我们需要回顾一些计算机体系架构方面的基础知识,搞清楚 CPU、寄存器、内存

taylorswift的博客 1116

函数调用详解

前几天忙里偷闲重做6.828,发现在lab 1 exercise 11卡住了,才发现之前觉得很熟了的函数调用已经因为太久没接触忘了,一年没有用过这些东西了。 看了几篇博客,发现理解还是不够深入,只能自己再手动测一下试一试了。 写了一个C文件,叫temp.c #include <stdio.h> int double_add_int(int a, int b) { int c = a; int d = b; int e = a + b + c + d; retu

辣鸡的博客 1299

函数调用分析

操作系统把磁盘上可执行文件加载到内存运行之前, 需要做很多工作, 其中很重要的一件事就是把可执行文件中的代码, 数据存放到内存 中合适的位置, 并分配和初始化程序运行过程中必须的堆, 所有准备工作完成之后操作系统才会调度程序起来运行.进程在内存中布局主要分为4个区域: 代码区, 数据区, heap和stack.

qq_43142509的博客 2826
上一篇: 文件系统之inode索引
下一篇: 深入理解任务堆栈以及堆栈溢出
Boooooots
博客等级 码龄8年 76粉丝 32原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值