0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

来聊聊函数是怎么传入参数的

Q4MP_gh_c472c21 来源:未知 作者:李倩 2018-07-05 15:57 次阅读

今天,我们来聊聊函数是怎么传入参数的,我们都知道,当一个函数调用使用少量参数(ARM上是少于等于4个)时,参数是通过寄存器进行传值(ARM上是通过r0,r1,r2,r3),而当参数多于4个时,会将多出的参数压入栈中进行传递(其实在函数调用过程中也会把r0,r1,r2,r3传递的参数压入栈),具体是什么实现的呢,下面我们来具体看看。

函数栈

首先我们需要了解一下linux下一个进程的内存地址空间是如何布局的,在linux中,0~3G的虚拟地址为进程所有,3G~4G由内核所使用,每一个进程都有自己独立的0~3G内存地址空间。当进程进行函数调用时,我们都知道传入被调用函数的参数是通过栈进行操作的,这里我们只需要简单了解一下linux的内存地址空间中的栈是自顶向下生长的,就是栈底出于高地址处,栈顶出于低地址处。

好的,简单了解了内存地址空间的栈后,我们还需要简单了解一下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 (1, 2, 3);

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上我几个参数和不定参数的情况通过汇编代码查看又不相同,今天讲的就当做一个入门知识吧。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 寄存器
    +关注

    关注

    30

    文章

    5025

    浏览量

    117706
  • Linux
    +关注

    关注

    87

    文章

    10986

    浏览量

    206720
  • 函数
    +关注

    关注

    3

    文章

    3864

    浏览量

    61306

原文标题:你知道ARM下函数是怎么传入参数的吗?

文章出处:【微信号:gh_c472c2199c88,微信公众号:嵌入式微处理器】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    keil rtx重入函数无法正常传入该怎么办?

    使用KEIL C51然后用到RTX,然后多任务需要同时调用A函数,这个A函数带有一个参数我在函数上加入了reentrant关键字就是为了可以重入,现在的问题是当任务调用A
    发表于 10-23 23:19

    labview调用halcon程序如何传入参数

    各位大神,labview调用halcon的hdev程序时,如何给halcon传入参数?比如传入图像,labview如何获取这个传入参数的接口
    发表于 05-12 22:43

    U16的数据在传入函数之后为什么会被置零

    原本U16的数据,传入函数之后变成U8了,高8位被置零了。后发现罪魁祸首,函数定义和函数声明时参数给定的长度不一,最后统一更改为U16之后,
    发表于 07-14 06:41

    不定参数个数的函数如何定义的呢

    在学习使用C语言的时候都会告知main函数是可以接入多个参数的,那么问题来了,不定参数个数的函数如何定义的呢,它是否可以在单片机中使用呢定义和使用//首先引用#include //定义
    发表于 07-15 07:23

    在CH579上移植rtthread并使用蓝牙功能,请问传入Peripheral_TaskID参数的意义是什么?

    大家好,我现在尝试在CH579上移植rtthread并使用蓝牙功能。移植过程中发现启动设备需要用到GAPRole_PeripheralStartDevice函数。但是这个函数必须传入
    发表于 08-26 06:15

    请问如何调整LwIP以接收更多传入连接?

    ECONNRESET 发生的原因。我已经将其追溯到调用的“tcp_abandon”函数。文档指出此功能“放弃连接并可选择将 RST 发送到远程主机。删除本地协议控制块。这是在连接因内存不足而被终止时完成的。” 我试过调整 LwIP 的内存设置但无济于事。任何人都可以建议设置
    发表于 01-04 08:32

    程序调试时如何实时传入命令参数

    程序调试时如何实时传入命令参数
    发表于 10-25 08:25

    学会在Linux下使用getopt函数来获取传入参数

    在linux下有一个函数叫getopt就可以写成-r -l -i 的形式,下面是一个使用openssl通信的程序,需要4个参数服务器ip -i、服务器端口-p、证书地址-c、私匙地址-s代码如下,重点看while循环
    发表于 05-06 17:17 1072次阅读

    C语言&单片机不定参数个数的函数定义

    在学习使用C语言的时候都会告知main函数是可以接入多个参数的,那么问题来了,不定参数个数的函数如何定义的呢,它是否可以在单片机中使用呢定义和使用//首先引用#include <
    发表于 11-29 09:51 8次下载
    C语言&单片机不定<b class='flag-5'>参数</b>个数的<b class='flag-5'>函数</b>定义

    python高阶函数详解

    python高阶函数 1. map 函数 map 函数,它接收两个参数,第一个参数是一个函数对象
    的头像 发表于 03-02 16:47 1121次阅读
    python高阶<b class='flag-5'>函数</b>详解

    基于Simulink搭建保护原型函数

    BMS保护包括过充保护、过流保护、高温保护等等保护类型较多,但是如果用函数封装的角度去理解,大多数保护类型函数原型是一样的,只不过传入函数参数
    的头像 发表于 03-10 14:38 577次阅读
    基于Simulink搭建保护原型<b class='flag-5'>函数</b>

    函数参数

    对比功能块,函数没有任何他们保存参数值的内存。在函数激活时,本地数据只中临时地贮存。由于这个原因,当调用函数时,所有在函数声明部分定义的形式
    的头像 发表于 04-27 15:26 424次阅读
    <b class='flag-5'>函数</b>的<b class='flag-5'>参数</b>

    函数类型和函数指针类型的区别

    平时用的更多的是函数指针类型,比如作为函数参数传入回调函数等等。实际上函数类型也是可以作为
    发表于 10-24 14:27 149次阅读

    函数参数的分类有哪些

    一、函数参数的分类 函数参数分为两类:形参 及 实参 形参:形参是在创建过程中声明的参数,如果不给形参
    的头像 发表于 11-14 11:13 1041次阅读

    input结果如何传入参数

    当我们谈论输入结果传入参数时,可以理解为我们需要将某个结果作为参数传递给一个函数或者算法,以便对其进行进一步的处理或分析。这样做通常是为了提高代码的复用性、灵活性以及整体的效率。 在编
    的头像 发表于 11-30 10:07 337次阅读