|
发表于 2020-9-18 10:26:28
|
显示全部楼层
本楼为最佳答案
 本代码只适用于win32系统
- #include <stdio.h>
- #include <windows.h>
- //已初始化全局变量
- long g_Init_v = 1000;
- //未初始化全局变量
- long g_Uninit_v;
- void fun1()
- {
- long a = 100;
- long b = 200;
- long c = a + b;
- }
- //获取一个函数的堆栈帧
- // C 函数调用参数传递,先传a,再传b,最后传返回地址
- // PASCAL 函数调用参数传递,先传b,再传a,最后传返回地址
- long stackframe(long a,long b)
- {
- //取参数a的地址
- long address_a = (long)(&a);
- //取参数b的地址
- long address_b = (long)(&b);
- //以高地址为堆栈帧的起始地址
- long stackBegin = address_a > address_b ? address_a : address_b;
-
- //最后定义的变量为堆栈帧的结束地址
- //堆栈帧大小 = 起始地址 - 结束地址 (因为栈是从高地址向低地址走)
- long stackframesize = stackBegin - (long)(&stackframesize);
- return stackframesize;
- }
- int main()
- {
- //仅试用于win32系统
- //获取系统系统,主要是获取内存页面大小
- //win32的内存页面大小通常为4k,即4096字节
- SYSTEM_INFO si = {0};
- GetSystemInfo(&si);
-
- //获取主函数地址,C程序中主函数为进程入口
- long address_of_main = (long)main;
- //或取一个函数fun1的地址
- long address_of_fun1 = (long)fun1;
-
- //获取代码段地址,取值最小的函数地址为代码起始地址并按页面大小对齐
- long address_of_code = (address_of_main < address_of_fun1 ? address_of_main : address_of_fun1) / si.dwPageSize * si.dwPageSize;
- //获取已初始化全局变量地址
- long address_of_InitV = (long)(&g_Init_v);
- //已初始化全局变量地址按页面大小对齐
- long address_of_data1 = address_of_InitV / si.dwPageSize * si.dwPageSize;
- //获取未初始化全局变量地址
- long address_of_UninitV = (long)(&g_Uninit_v);
- //未初始化全局变量地址按页面大小对齐
- long address_of_data2 = address_of_UninitV / si.dwPageSize * si.dwPageSize;
- //获得一个函数的堆栈帧大小
- long stackframesize = stackframe(0,0);
-
- return 0;
- }
复制代码 |
|