如何用c语言体现进程地址空间
进程地址空间是操作系统为一个特定进程创建的一组可访问地址。众所周知,进程地址空间由文本/代码段,数据(已初始化和未初始化)段,堆栈和堆组成。在此作业中,要求您使用C语言编写程序,以探索如何将进程地址空间映射到内存中。特别是,您的代码应至少有两个文件(.c)才能将多个目标文件合并为一个可执行目标文件,并且必须存在交叉引用。例如,文件1调用文件2中定义的函数。
在您的代码中,您应该想出一种方法来显示所有不同段的位置(如上所述),即起始/结束地址或位于指定段中的变量的地址。
在您的实现中回答以下问题:a)一个堆栈帧的大小是多少? b)代码段的起始地址是什么? c)您代码中每个函数的地址是什么? d)初始化的全局变量和未初始化的变量的地址是什么?
小白在线等求助 感谢大佬!!!! 用c语言写代码 本代码只适用于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;
} xieglt 发表于 2020-9-18 10:26
本代码只适用于win32系统
为什么都用long, 用int可以吗? zsyyf 发表于 2020-9-18 11:49
为什么都用long, 用int可以吗?
win32系统,int 和 long 是一样的 xieglt 发表于 2020-9-18 11:53
win32系统,int 和 long 是一样的
感谢大佬
页:
[1]