一 函数栈帧
1.认识相关寄存器
eax:通用寄存器,保存临时数据,常用于返回值。
ebx:通用寄存器,保存临时数据。
ebp:栈底寄存器。
esp: 栈顶寄存器。
eip: 指令寄存器,保存当前指令的下一条指令的地址。
2.认识相关汇编命令
mov: 数据转移指令
push: 数据入栈,同时esp栈顶寄存器也要发生改变。
pop:数据弹出至指定位置,同时esp栈顶寄存器也要发生改变。
sub:减法命令。
add: 加法命令。
call:函数调用,①压入返回地址。②转入目标函数。
jump:通过修改eip,转入目标函数,进行调用。
ret:恢复返回地址,压入eip,类似pop eip 命令。
3.函数栈帧总结
1.临时变量的形成是在函数正式被调用之前就形成了的。
2.形参实例化的顺序是从右向左的。
3.函数调用完毕,栈帧结构被释放。
4.临时变量具有临时性的本质:栈帧具有临时性。
5.调用函数是有成本的,成本体现在时间和空间上,本质是形成与释放栈帧有成本。
6.函数调用,因拷贝所形成的临时变量,变量和变量之间的位置关系是有规律的。
二 可变参数列表
1.注意事项
2.原理
#include<stdio.h>
#include<stdarg.h>
//查找最大数据。
int FindMaxDate(int num, ...)
{
va_list arg; //定义可以访问可变参数部分的变量,其实是一个char*类型
va_start(arg,num); //使arg指向可变参数部分
int max = va_arg(arg, int); //根据类型,获取可变参数列表中的第一个数据
for (int i = 0; i < num - 1; i++)//获取并比较其他的
{
int curr = va_arg(arg, int);
if (max < curr)
{
max = curr;
}
}
va_end(arg);//arg使用完毕,收尾工作。本质就是讲arg指向NULL
return max;
}
int main()
{
int max = FindMaxDate(5,1,2,5,4,9);
printf("%d\n", max);
return 0;
}
三 命令行参数
1.main函数也是可以带参数的。
#include <stdio.h>
int main(int argc, char* argv[], char* envp[])
{
int i = 0;
for(i=0; i<argc; i++)
{
printf("%s\n", argv[i]);
}
return 0;
}
argc: 是个整型变量,表示命令行参数的个数(含第一个参数)。
argv :是个字符指针的数组,每个元素是一个字符指针,指向一个字符串。这些字符串就是命令行中的每一个参数(字符串)。
envp :是字符指针的数组,数组的每一个原元素是一个指向一个环境变量(字符串)的字符指针。