首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

C语言函数调用帧结构

(1)这里首先main函数建立自己的帧结构;main()函数是由__tCRTStartup()函数调用的,所以mainCRTStratup()函数调用__tmainCRTStra()函数的时候就会从上为...然后继续执行下一条语句:mov ebp,esp即把esp的值赋给ebp,这样,ebp也就指向了现在esp的位置 然后sub esp 0C0h 这样就为main函数开辟了一段空间然后将ebx、esi、edi...如此一来,几乎所有的c函数都由如下两个指令开 始: push ebp mov ebp, esp 下一步,fun必须为它的局部变量分配空间,同时,也必须为它可能用到的一些临时变量分配 空间。...比如,foo中的一些C语句可能包括复杂的表达式,其子表达式的中间值就必须得有地方存放。...如果在函数调用前,EAX,ECX和EDX寄存器的值被保存在中,调用者main函数现在可以把它们弹出。这个动作之后,顶就回到了我们开始整个函数调用过程前的位置。这样整个函数调用就结束了

1.3K30

C语言 | 函数调用

C语言函数调用的形式 一般形式 函数名(实参表列) 函数调用语句 把函数调用单独作为一个语句。 函数参数 函数调用作为另一个函数调用时的实参。 调用函数并不一定要求包括分号。...只有作为函数调用语句才需要有分号。如果作为函数表达式或函数参数,函数调用本身是不必有分号的。 C语言函数调用时的数据传递 在调用有参函数时,主调函数和被调函数之间有数据传递关系。...C语言函数调用的过程 在定义函数中指定的形参,在未出现函数调用时,它们并不是占内存中的存储单元。 将实参对应的值传递给形参。 通过return语句将函数值带回到主调函数调用结束,形参单元被释放。...C语言函数调用案例 #include//头文件 int maxNumber(int num1,int num2);//函数声明 int main()//主函数 {   int num1...100道C语言源码案例请去公众号:C语言入门到精通

3.3K10
您找到你想要的搜索结果了吗?
是的
没有找到

7.2 C语言调用函数

01函数调用的形式 1、一般形式 函数名(实参表列) 2、函数调用语句 把函数调用单独作为一个语句,如c=max(a,b),max(a,b)是一次函数调用,它是赋值表达式中的一部分。...3、函数参数 函数调用作为另一个函数调用时的实参。 4、调用函数并不一定要求包括分号,只有作为函数调用语句才需要有分号。如果作为函数表达式或函数参数,函数调用本身是不必有分号的。...02 函数调用时的数据传递 1、在调用有参函数时,主调函数和被调函数之间有数据传递关系。...03 函数调用的过程 1、在定义函数中指定的形参,在未出现函数调用时,它们并不是占内存中的存储单元。 2、将实参对应的值传递给形参。 3、通过return语句将函数值带回到主调函数。...3、在定义函数时指定的函数类型一般应该和return语句中的表达式类型一致。 4、函数类型决定返回值类型。 C语言 | 求1+2+...100的和 更多案例可以go公众号:C语言入门到精通

2.4K3027

C语言函数调用约定

C语言默认调用约定,参数通过从右向左的顺序压调用函数恢复堆栈 1265: ff 75 fc push DWORD PTR [ebp-0x4...是从左到右入还是从右到左入; [参数弹出方式]:函数调用后,由谁来把恢复原状? 函数调用结束后需要将压入中的参数全部弹出,以使得函数调用前后保持一致。...函数调用惯例在函数声明和函数定义时都可以指定,语法格式为: ‌返回值类型 调用惯例 函数名(函数参数) int __cdecl max(int m, int n); // __cdecl是C语言默认的调用约定...函数的第一个和第二个DWORD参数通过ecx和edx传递,剩下的参数按照从右到左的顺序入 cdecl: C语言默认,变参函数 由于每次函数调用都要由编译器产生还原的代码,所以使用 __cdecl...所以,所有非叶子结点调用函数,都必须调整RSP的地址为16n+8,来使对齐。

11710

上理解 Go语言函数调用

综上在函数调用中,关于参数的传递我们可以知道两个信息: 参数完全通过传递 从参数列表的右至左压 下面是调用 add 函数之前的调用调用详情: [call stack] 当我们准备好函数的入参之后...) 1 (dlv) print *(*int)(uintptr(0x000000c000044758)+16) 2 下面是调用 add 函数之后的调用调用详情: [call stack2] 从上面的...小结以下调用规则: 参数完全通过传递 从参数列表的右至左压 返回值通过传递,返回值的空间在参数之前 函数调用完毕后,调用方(caller)会负责的清理工作 结构体方法:值接收者与指针接收者...其实这段汇编和其他的函数调用的汇编是一样的,没啥好讲的,在调用 test 函数之前就是做了一些的初始化工作。...函数地址值存在 main 调用顶,然后调用完 test 函数之后会将存放在 (SP) 的 test.func1 函数地址值写入到 AX 中,然后执行调用下面的指令进行调用: 0x0031 00049

2K30

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

调用函数在返回之前不必恢复 r12。 4. 寄存器 r13 是指针 sp。它不能用于任何其它用途。sp 中存放的值在退出被调用函数时必须与进入时的值相同。 5....这里以一段简单的 c 语言为例: #include int m = 8; int fun(int a,int b) { int c = 0; c = a + b;...1.程序在内存分布区域 2.全局变量m赋值 3.保存进入main之前的底, fp-sp之间是当前函数 4.函数main的已经准备好了 5.i入 6.j入 7.准备函数fun的调用, 形参反向入...fun代码 13.c 14.可以看到函数fun的数据 形参a,b 在上一层函数中....此步取值到加法器中进行加法运算,再赋值给c 15.c赋给返回值,填入上面的留空位置 16.底恢复上一层 17.lr赋值给pc, 实现了跳转 18.返回值赋值给全局变量m 19.前面函数调用的形参已经无用

13.4K83

函数调用堆栈图-c语言

我们就使用一个简单的c语言程序来对描述一下在函数调用的时候都发生了什么。 ?...在程序的执行当中,我们一般都是按照从右向左的方式去处理的,这里也不例外,我们可以发现当我们调用sum函数对数字1和数字2进行处理的时候,将数字2和1依次压入中,这个时候堆栈的情况是这个样子的,esp的值已经减...此时的堆栈是没有发生变化的,现在开始到了函数调用的关键阶段了。...但是此时还有个问题,esp并没有回到调用前的位置,所以堆栈还是没有平衡的,如果堆栈不平衡,那在不断的执行的过程中,就会发生堆栈溢出,这里编译器是使用外平的方式来使堆栈恢复平衡的,它在esp的基础上增加了...还有另一种方式是使用内平的方式,即在函数内部就将堆栈恢复平衡,使用ret 8的方式。 再往后面的操作就是main函数的堆栈平衡的处理了,与上面的函数调用类似,就不提了。

2.7K10

C语言函数帧详解

引用百度百科:C语言中,每个帧对应着一个未运行完的函数帧中保存了该函数的返回地址和局部变量。从这句话中,可以提炼以下几点信息: 帧是一块因函数运行而临时开辟的空间。...每调用一次函数便会创建一个独立帧。 帧中存放的是函数中的必要信息,如局部变量、函数传参、返回值等。 当函数运行完毕帧将会销毁。 ​ 下面进入主题,图解函数帧的创建与销毁过程。...3.1 main函数帧创建 ​ 根据VS2013编译器调试,调用堆栈,不难发现main函数调用链条如下: 很显然main函数在被调用时,创建了帧。...进入Add()函数,可以看出这与此前main函数开辟帧的过程类似,说明Add()函数调用又开辟了一块独立的帧。...3.3.4 函数返回 PLAINTEXT return c; 00AA13EE mov eax,dword ptr [ebp-8] 将返回值传递至寄存器eax中,因此在函数调用结束函数帧被销毁时

1.9K20

C语言函数调用详解】——传值调用&传址调用

num1,num2的目的,我们看看结果是什么样的: 因此,传值调用,要想在函数内部交换两个变量的值,是不可行的。...这里就需要传址调用。 二.传址调用 那什么是传址调用呢?这里的“址”指的是地址。 传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式。...这种传参方式可以让函数函数外边的变量建立起真正的联系,也就是函数内部可以直接操作函数外部的变量。...那现在我们用传址调用的方法对上面的函数重新进行实现: #include //正确的版本 void Swap2(int* px, int* py) { int tmp = 0; tmp...以上就是对函数调用的两种方式,传值调用和传址调用的介绍,欢迎大家指正,我们一起进步!!!

16510

C语言函数调用-学习十七

max(a,b); 按函数调用在程序中出现的形式和位置来分, 可以有以下3种函数调用方式: 1.函数调用语句 把函数调用单独作为一个语句。...如: printf_star(); 这时不要求函数带回值,只要求函数完成一定的操作。 2.函数表达式 函数调用出现在另一个表达式中。如:c=max(a,b); 这时要求函数带回一个确定的值。...3.函数参数 函数调用作为另一函数调用时的实参。如:m=max(a,max(b,c)); 其中 max(b,c) 是一次函数调用,它的值作为max另一次调用的实参。...C语言规定,实参变量对形参变量的数据传递是“值传递”,即单向传递,只由实参传给形参,而不能由形参传回来给实参。 在内存中,实参单元与形参单元是不同的单元。...add(a, b); printf("结果:%f\n", c); } 如果已经在文件的开头( 所有函数之前),对本文中所调用函数进行了声明,则在各函数中不必对其所调 用的函数再作声明。

1.9K30

c语言调用bool函数,C语言中 bool的用法

bool可用于定义函数类型为布尔型,函数里可以有 return TRUE; return FALSE 之类的语句。...提高程序的可读性 bool类型的变量只可能有两个值true或false,在没有统一的布尔类型在大型的工程项中特别是用到第三方程序库时,可能使用不同的手段模拟布尔类型以提交代码的可读性,这样会使得代码有些混乱,C语言中引入了...2、提高程序的性能 bool在绝大多数编译器编译时都将其实现为1字节,即sizeof(bool)的值为1,加上其只有两个值的值域{true, false},是C语言中最小的数据类型了。...虽然char、unsigned char和signed char类型在C语言中没有特定的实现要求,但一般也实现为一个字节,这样看来与bool类型从内存空间的占用上并没有性能上的差异。...参考资料来源:百度百科——BOOL 发布者:全程序员长,转载请注明出处:https://javaforall.cn/141897.html原文链接:https://javaforall.cn

3.4K50

C语言基础:函数的定义与调用

大家好,又见面了,我是你们的朋友全君。 在前面内容中我们调用了一个标准C的库函数,叫printf,那么如果我们想自己定义函数应该如何来编写程序呢?定义函数又有什么好处呢?...我们看下面程序: #include main() { int a = 2, b = 3; int c; int wrongplus(int a, int b); c = wrongplus...我们在调用一个函数时,需要向这个函数传其需要的参数,例如a和b这两个变量,并可以指定另一个变量用于接收这个函数执行后的返回值,比如变量c就接收了函数wrongplus()的返回值,结果为7。...调用函数时向函数传入的参数称作实际参数,简称实参,而函数体内部用于接收外部调用时传入的参数的参数称为形式参数,简称形参。...欢迎关注公众号:编程外星人 发布者:全程序员长,转载请注明出处:https://javaforall.cn/147528.html原文链接:https://javaforall.cn

98610

C 语言C 语言 函数 详解 ( 函数本质 | 顺序点 | 可变参数 | 函数调用 | 函数活动记录 | 函数设计 )

, 这些简单问题就可以作为一个个的函数来编写; 2.C语言程序 : 将一个复杂的程序拆解成一个个模块 和 库函数; 一个复杂的 C 语言程序有几十上百万行代码, 这些代码可以分解成若干模块来实现, 即分解成一个个的函数来实现...的思想在 C 语言 中的核心就是 函数; 4.分解函数 : 复杂问题 分解后的过程可以分为一个个函数一步步实现; ---- 3....语言规范中没有规定函数参数必须从左到右进行计算赋值; 3.运算符编程注意点 : C语言中大多数的运算符的操作数求值顺序也是不固定的, 依赖于编译器的实现; 4.示例 : 如 int ret = fun1...C 语言 函数 的 缺省认定 (n) 标题3 ---- 函数缺省认定简介 : 1.描述 : C 语言中 默认 没有类型的 参数 和 返回值 为 int 类型; 2.举例 : fun(i) {...被调用函数, 返回值被返回给 调用函数 ; 2.调用约定作用 : 调用约定 是 用来规定 ① 参数 是通过什么方式 传递到 空间 ( 活动记录 ) 中, ② 由谁来 清理 ; 3.参数传递顺序

1.2K30

C语言函数——帧的创建和销毁

✨作者:@平凡的人1 ✨专栏:《C语言从0到1》 ✨一句话:凡是过往,皆为序章 ✨说明: 过去无可挽回, 未来可以改变 ---- 目录 前言 什么是 什么是函数帧 认识相关寄存器和汇编指令...寄存器 相关的汇编指令: 函数调用堆栈 函数帧的创建 分析帧的创建: 为什么会出现“烫烫烫”: 分析main函数中的核心代码: 分析Add函数的传参 函数调用过程 函数帧的销毁下 结语✍ --...下面我们要先来理解一些概念 什么是 在学习C语言中,我们关注内存中的3个区域,区、堆区和静态区 那究竟什么是呢?...⏩ (stack)是现代计算机程序里最为重要的概念之一,几乎每一个程序都使用了,没有就没有函 数,没有局部变量,也就没有我们如今看到的所有的计算机语言。...每一次函数调用,都要为本次函数调用开辟空间,就是函数帧的空间。 2.这块空间的维护是使用了2个寄存器: esp 和 ebp , ebp 记录的是底的地址, esp 记录的是顶的地址。

50510

函数调用过程(帧)

开发环境 Ubuntu 14.04(32bits) GCC 编辑器 Cmd Markdown 画图工具 Processon 1,函数调用过程 今天先介绍下基本的函数调用过程,即帧。...1.1帧 每个函数调用都对应一个帧。每个帧由ESP和EBP寄存器来确定。每个函数执行时,其局部变量都是在自己对应的帧内分配内存。...假设A函数调用B函数,此时正在执行B函数,需要指出的是,当执行完当前函数B后,返回调用函数A,此时执行函数B时,为B函数的局部变量分配的的内存空间也就不存在了。...,此处将j的值压 movl 20(%esp), %eax //将变量i的值赋给eax寄存器 movl %eax, (%esp) //将变量i的值压 call test //调用test函数,...函数时,对应的帧见下图 当函数test返回后,main函数帧如下图

79120
领券