写一个程序从VM进程地址空间理解函数激活(函数栈)以及代码段(正文段)
Posted 狱典司
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了写一个程序从VM进程地址空间理解函数激活(函数栈)以及代码段(正文段)相关的知识,希望对你有一定的参考价值。
- 理解的过程看输出就能明白
- 输出结果:
- 代码如下:
#include<iostream>
#include<stdio.h>
#include<typeinfo>
#include <stdlib.h>
using namespace std;
int func1(int val, int *preAddr){
int a = 0;
unsigned int i;
int *ad = &a;
printf("the address of func1:%p\\n", &func1);
if(preAddr != 0) printf("the Pre-address of a(十进制): %d\\n", preAddr);
printf("the address of a in func1(十进制): %d\\n", ad);
printf("the address of a in func1(32位十六进制): %p\\n", &a);
long long int len = (int&)preAddr - (int&)ad;
preAddr = ad;
if(len > 0) printf("由func1两次递归中各自a的地址差值可知栈中函数激活的长度为 : %lld Bytes\\n", len);
printf("__________________________________________________________\\n");
val++;
while(val < 2) val += func1(val,preAddr);
return val;
}
void func2(){
int a = 0;
}
void func3(){
int a = 0;
}
void func4(){
int a = 0;
}
void func5(){
int a;
}
void func6(){
int a;
}
void func7(){
int a;
a = 0;
}
void func8(){
int a;
a = 0;
}
#define SHW_ADR(ID,I) printf("The %s is at address: %d\\n",ID,&I);//打印地址宏
int main(){
func1(0,0);
SHW_ADR("main ",main);//查看代码段main函数位置
SHW_ADR("func2 ",func2);
SHW_ADR("func3 ",func3);
SHW_ADR("func4 ",func4);
int *ad3 = ( (int*)(&func3) ); //做函数类型到指针类型的转换,难点
int *ad4 = ( (int*)(&func4) );
int lenOfFunc3 = (int&)ad4 - (int&)ad3;
printf("可以看到func2~4的起始地址间隔相等,且它们的函数体也相等,\\n故可以得出func2~func4的大小就是他们起始地址的间隔:%lld Bytes\\n",lenOfFunc3);
printf("__________________________________________________________\\n");
printf("在上述结果的基础上,我们设置四个函数:\\n(1) func5函数:只做int a的声明\\n(2) func6函数:与func5一致,为计算func5的大小\\n(3) func7函数:在func5的基础上给a赋值\\n(4) func8函数:与func7一致,为计算func7的大小\\n");
SHW_ADR("func5 ",func5);
SHW_ADR("func6 ",func6);
SHW_ADR("func7 ",func7);
SHW_ADR("func8 ",func8);
int *ad5 = ( (int*)(&func5) ); //做函数类型到指针类型的转换,难点
int *ad6 = ( (int*)(&func6) );
int lenOfFunc5 = (int&)ad6 - (int&)ad5;
printf("func5函数大小为:%d Bytes\\n",lenOfFunc5);
int *ad7 = ( (int*)(&func7) ); //做函数类型到指针类型的转换,难点
int *ad8 = ( (int*)(&func8) );
int lenOfFunc7 = (int&)ad8 - (int&)ad7;
printf("func7函数大小为:%d Bytes\\n\\n",lenOfFunc7);
printf("由于func7只比func5多了一个赋值语句,\\n故可知一个赋值语句的大小大约是:%d Bytes\\n", lenOfFunc7-lenOfFunc5);
return 0;
}
需要注意的是各种类型数据地址的类型转化
以上是关于写一个程序从VM进程地址空间理解函数激活(函数栈)以及代码段(正文段)的主要内容,如果未能解决你的问题,请参考以下文章