谈谈arm下的函数栈
引言
这篇文章简要说说函数是怎么传入参数的,我们都知道,当一个函数调用使用少量参数(ARM上是少于等于4个)时,参数是通过寄存器进行传值(ARM上是通过r0,r1,r2,r3),而当参数多于4个时,会将多出的参数压入栈中进行传递(其实在函数调用过程中也会把r0,r1,r2,r3传递的参数压入栈),具体是什么实现的呢,我们看看。
函数栈
首先我们需要了解一下linux下一个进程的内存地址空间是如何布局的,在linux中,0~3G的虚拟地址为进程所有,3G~4G由内核所使用,每一个进程都有自己独立的0~3G内存地址空间。当进程进行函数调用时,我们都知道传入被调用函数的参数是通过栈进行操作的,这里我们只需要简单了解一下linux的内存地址空间中的栈是自顶向下生长的,就是栈底出于高地址处,栈顶出于低地址处。
JA9X]0PX8B%ZKS.png)

好的,简单了解了内存地址空间的栈后,我们还需要简单了解一下EBP和ESP这两个寄存器,EBP是用保存栈低地址的,而ESP用于保存栈顶地址,而每一次函数调用会涉及到一个栈帧,

举个实例详细说明一下一个函数帧的特点,比如
/* B被A调用
* 参数:data1, data2, data3
* 局部变量: s1, s2, s3 */
void B (int data1, int data2, int data3)
{
int b_s1;
int b_s2;
int b_s3;
} /* A调用B函数 */
void A (void)
{
int a_s1;
int a_s2;
int a_s3; B (, , );
printf ("1\n");
}
在以上例子中栈帧情况如下图所示

从图例中可以看出,当A函数没有调用B函数时,A函数的栈帧只保存着局部变量,而EBP(栈底指针)指向的是A函数的函数栈帧头,而当A函数调用B函数时,A函数会将B函数所需要的参数从右往左压入栈(在例子中先压入3,之后是2,最后是1),之后会将A调用完B之后所需要运行的第一条指令压入栈,此时建立一个B的栈帧,具体流程:
- 从右往左将B函数所需参数压入栈
- 压入执行完B函数之后的第一条指令地址
- 建立B栈帧
- 压入A栈帧的栈底
- 压入B函数保护的寄存器
- 压入B函数的局部变量
小结
其实每一种处理器架构所使用的方式都不一样,在arm上我几个参数和不定参数的情况通过汇编代码查看又不相同,之后反汇编后研究透了会再发布一篇博文专门说这个,现在这篇就当做一个入门知识吧。
谈谈arm下的函数栈的更多相关文章
- 代码 or 指令,浅析ARM架构下的函数的调用过程
摘要:linux程序运行的状态以及如何推导调用栈. 1.背景知识 1.ARM64寄存器介绍: 2.STP指令详解(ARMV8手册): 我们先看一下指令格式(64bit),以及指令对于寄存机执行结果的影 ...
- arm平台的调用栈回溯(backtrace)
title: arm平台的调用栈回溯(backtrace) date: 2018-09-19 16:07:47 tags: --- 介绍 arm平台的调用栈与x86平台的调用栈大致相同,稍微有些区别, ...
- c函数调用过程原理及函数栈帧分析
转载自地址:http://blog.csdn.net/zsy2020314/article/details/9429707 今天突然想分析一下函数在相互调用过程中栈帧的变化,还是想尽量以比 ...
- online ddl 使用、测试及关键函数栈
[MySQL 5.6] MySQL 5.6 online ddl 使用.测试及关键函数栈 http://mysqllover.com/?p=547 本文主要分为三个部分,第一部分是看文档时的笔记:第 ...
- broadcom6838开发环境实现函数栈追踪
在嵌入式设备开发中.内核为内核模块的函数栈追踪已经提供了非常好的支持,但用户层的函数栈追踪确没有非常好的提供支持. 在网上收集学习函数栈跟踪大部分都是描写叙述INTER体系架构支持栈帧的实现机制.或者 ...
- [转帖]Linux下fork函数及pthread函数的总结
Linux下fork函数及pthread函数的总结 https://blog.csdn.net/wangdd_199326/article/details/76180514 fork Linux多进程 ...
- arm下dlsym返回的符号地址居然不是偶对齐的。
我们都知道在写汇编函数过程都会偶对齐,而gcc编译器都会将函数编译为cpu字长对齐的地址.arm指令集是固定32位指令长度,thumb指令集是固定16位指令长度, 但是运行在arm下的程序,dlsym ...
- 解决Python3下map函数的显示问题
今天小编就为大家分享一篇解决Python3下map函数的显示问题,具有很好的参考价值,希望对大家有所帮助.一起跟随小编过来看看吧map函数是Python里面比较重要的函数,设计灵感来自于函数式编程.P ...
- Cortex-M3双堆栈MSP和PSP+函数栈帧
为了防止几百年以后找不到该文章,特此转载 ------------------------------------------------开始转载--------------------------- ...
随机推荐
- UCOS2_STM32F1移植详细过程(四)
Ⅰ.概述 上一篇文章是讲述uC/OS-II Ports下面os_cpu_a.asm.os_cpu_c.c和os_cpu.h文件底层端口代码的移植(修改)和说明,接着上一篇文章来讲述关于UCOS移植应用 ...
- 如何查找STM32开发资料
Ⅰ.概述 该文写给那些处于初学ST芯片开发.英文不好而又想偷懒的人. 该文主要的目的是提醒大家:学习一门技术是需要舍得花功夫,捷径是你在起点与终点之间不断的探索,最终总结出来的一条适合自己的路. 下面 ...
- bhrs报表年结步骤
--前期准备数据三个表数据: s_subjtotal_year, subject_item, branch ,decrsubjtotal---informix 查看数据库剩余空间select d.na ...
- 一步一步实现Linux设备驱动的Helloworld模块
学了那么多程序语言,总是有一个Hello world开头,不禁感叹Hello world的强大.呵呵,废话少说,咋们的故事当然要从这个Hello world开始. 先查看自己OS使用的内核版本[don ...
- hdu 1622 Trees on the level
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1622 小白书上的题... #include<algorithm> #include< ...
- SqlBulkCopy与触发器,批量插入表(存在则更新,不存在则插入)
临时表:Test /****** 对象: Table [dbo].[Test] 脚本日期: 05/10/2013 11:42:07 ******/ SET ANSI_NULLS ON GO SET Q ...
- MongoDB 数据类型
MongoDB支持许多数据类型的列表下面给出: String : 这是最常用的数据类型来存储数据.在MongoDB中的字符串必须是有效的UTF-8. Integer : 这种类型是用来存储一个数值.整 ...
- Qt:禁止qDebug的输出
Qt:禁止qDebug的输出 在工程的.pro文件里加上以下编译批令即可: DEFINES += QT_NO_DEBUG_OUTPUT
- cocos游戏的真正入口,用C++实现的demo版本
1.cocos游戏的出发点 在main函数中有一句: return CCApplication::sharedApplication()->run(); 2.经过层层深入发现,真正的入口: ...
- PSP0表格
一 项目计划日志 周活动总结表 姓名:陆宇 日期:3.1 ...