[C语言]函数栈帧的创建和销毁
C语言 函数 创建 销毁 栈帧
2023-06-13 09:18:27 时间
函数栈帧的创建和销毁::
ebp,esp这两个寄存器中存放的是地址,这两个地址是用来维护函数栈帧的,edp被称为栈底指针,esp被称为栈顶指针。push:压栈:给栈顶放一个元素。pop:出栈:给栈顶删一个元素,lea:加载有效地址。dword=4byte。
int Add(int x,int y)
{
push ebp
mov ebp,esp
push ebx
push esi
push edi
lea edi [ebp+FFFFFF34h]
mov ecx,33h
mov eax,0CCCCCCCh
rep stos dword ptres:[edi]
int z = 0;
mov dword ptr[ebp-8] 0
z = x + y;
mov eax,dword ptr [ebp+8]
add eax,dword ptr [ebp+0Ch]
mov dword ptr [ebp-8] eax
mov eax,dword ptr [ebp-8]
pop edi
pop esi
pop ebx
mov ebp,esp
pop ebp
ret
}
int main()
{
push ebp
mov ebp,esp
sub esp,0E4h
push ebx
push esi
push edi
lea edi,[ebp-0E4h]
mov ecx,39h
mov eax,0ccccccch
rep stos dword ptr es:[edi]
int a = 10;
mov dword ptr[ebp-8],0Ah
int b = 20;
mov dword ptr[ebp-14h],14h
int c = 0;
mov dword ptr[ebp-20h],0
c = Add(a,b);
mov eax,dword ptr [ebp-14h]
push eax
mov ecx,dword ptr [ebp-8]
push ecx
call 00C210E1
add esp,8 00C21450
mov dword ptr[ebp-20h],eax
printf("%d\n",c);
mov esi,esp
mov eax,dword ptr[ebp-20h]
push eax
push 0C25858h
call dword ptr ds:[00C29114]
add esp,8
cmp esi,esp
cabl 00C2133B
return 0;
}
解决问题:
1.局部变量是怎么创建的?
答:首先为此次函数调用创建函数栈帧,在函数栈帧找空间存放局部变量值。
2.为什么局部变量的值是随机值?
随机值是系统开辟完函数栈帧后系统随机放进去的。
3.函数是怎么传参的?
形参在刚开始调用之前就已经传过去了,形式参数从左向右传递。
4.形参和实参是什么关系?
形参是实参的临时拷贝,值相同但空间不同,因此改变形参的值不会影响实参的值。
5.函数调用结束后怎么返回的?
返回值并不会随着函数作用域的销毁而销毁,而是放在eax中准备返回,当通过pop出栈回到main函数中再将返回值放到局部变量中。
C语言编程训练
1.编写程序将三个整数从大到小输出
#include<stdio.h>
代码1
int main()
{
int a = 0;
int b = 0;
int c = 0;
int temp = 0;
scanf("%d %d %d", &a, &b, &c);
if (a < b)
{
temp = a;
a= b;
b = temp;
}
if (a < c)
{
temp = a;
a = c;
c = temp;
}
if (b < c)
{
temp = b;
b = c;
c = temp;
}
printf("%d %d %d", a, b, c);
return 0;
}
代码2:函数版
Swap(int* px, int* py)
{
int temp = *px;
*px = *py;
*py = temp;
}
int main()
{
int a = 0;
int b = 0;
int c = 0;
scanf("%d %d %d", &a, &b, &c);
if (a < b)
{
Swap(&a, &b);
}
if (a < c)
{
Swap(&a, &c);
}
if (b < c)
{
Swap(&b, &c);
}
printf("%d %d %d", a, b, c);
return 0;
}
2.编写程序打印1—100之间所有3的倍数的数字
#include<stdio.h>
打印1-100之间所有3的倍数的数字
代码1
int main()
{
int i = 0;
for (i = 1; i <= 100; i++)
{
if (i % 3 == 0)
printf("%d ", i);
}
return 0;
}
代码2
int main()
{
int i = 0;
for (i = 3; i <= 100; i += 3)
{
printf("%d ", i);
}
return 0;
}
3.编写程序求两个数的最大公约数
#include<stdio.h>
求两个数的最大公约数
代码1
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b);
int min = (a < b ? a : b);
int m = min;
while (1)
{
if (a % m == 0 & b % m == 0)
{
break;
}
m--;
}
printf("%d\n", m);
return 0;
}
代码2
辗转相除法:24 % 18 == 6 18 % 6 == 0
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b);
while (a % b)
{
int c = a % b;
a = b;
b = c;
}
printf("%d\n", b);
return 0;
}
优化
int main()
{
int a = 0;
int b = 0;
int c = 0;
scanf("%d %d", &a, &b);
while (c = a % b)
{
a = b;
b = c;
}
return 0;
}
4.编写程序计算1/1-1/2+1/3-1/4+1/5+......+1/99-1/100
#include<stdio.h>
int main()
{
int i = 0;
double sum = 0.0;
int flag = 1;
for (i = 1; i <= 100; i++)
{
sum = sum + flag*(1.0 / i);//一定不能写成1/i
flag = -flag;//不能写成flag=-1
}
printf("%lf\n", sum);
return 0;
}
5.求十个整数中最大值
#include<stdio.h>
代码1
int main()
{
//准备10个整数
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
//找出最大值
int i = 0;
int max = arr[0];//max不能赋值成0来比较负数
for (i = 1; i < 10; i++)
{
if (arr[i] > max)
{
max = arr[i];
}
}
printf("%d\n",max);
return 0;
}
代码2
int main()
{
int arr[10] = {0};
//输入数字
int n = 0;
for(n = 0;n < 10;n++)
{
scanf("%d",&arr[n]);
}
//找出最大值
int i = 0;
int max = arr[0];//max不能赋值成0来比较负数
for (i = 1; i < 10; i++)
{
if (arr[i] > max)
{
max = arr[i];
}
}
printf("%d\n",max);
return 0;
}
6.打印九九乘法口诀表
#include<stdio.h>
代码1
int main()
{
int i = 0;
for (i = 1; i <= 9; i++)
{
int j = 0;
for (j = 1; j <= i; j++)
{
printf("%d*%d=%-2d ", i,j, i * j);
}
printf("\n");
}
return 0;
}
代码2
int main()
{
int i = 0;
for (i = 1; i <= 9; i++)
{
int j = 0;
for (j = 1; j <= i; j++)
{
printf("%d*%d=%-2d ", j,i, i * j);
}
printf("\n");
}
return 0;
}
补:编写程序打印1到100之间数字9出现的个数
#include<stdio.h>
int main()
{
int i = 0;
int count = 0;//计数
for (i = 1; i <= 100; i++)
{
if (i % 10 == 9)//判断个位是不是9
count++;
if (i / 10 == 9)//判断十位是不是9
count++;
}
printf("count=%d\n", count);
return 0;
}
7.实现一个函数来打印乘法口诀表,行数列数自己指定
#include<stdio.h>
void print_table(int n)
{
int i = 0;
for (i = 1; i <= n; i++)
{
int j = 0;
for (j = 1; j <= i; j++)
{
printf("%d*%d=%-2d ", j, i, i * j);
}
printf("\n");
}
}
int main()
{
int n = 0;
scanf("%d", &n);
print_table(n);
return 0;
}
相关文章
- C语言中fprintf_c语言gets函数用法
- C语言例题:输入两个正整数m和n,求其最大公约数和最小公倍数。
- C语言读取txt文件实例
- C语言strstr函数实现
- C语言:数组作为函数参数(数组元素做实参,数组名称做形参)
- C语言函数的栈帧详解
- strstr()函数的使用说明(C语言)
- 玩转SQLite-11:C语言高效API之sqlite3_prepare系列函数
- 【C语言】动态内存管理(heap)
- C语言空(null)指针和NULL指针的区别详解
- C语言日期函数,日期处理函数
- C语言if语句
- 函数及其使用注意事项,C语言函数及使用注意事项详解
- EOF宏,C语言EOF宏详解
- gets和fgets函数及其区别,C语言gets和fgets函数详解
- strchr和strrchr函数及用法,C语言strchr和strrchr函数详解
- C语言ceil()函数:求不小于x的最小整数(向上取整)
- C语言islower()函数:判断一个字符是否是小写字母
- 探索Linux中C语言的功能知识(linux c语言函数)
- C语言搭建MySQL服务器 - 技术指引(c mysql 服务器)
- MySQL操作函数C语言实现(c mysql操作函数)
- 深入解析C语言中typedef的四个用途
- python和C语言混合编程实例