zsyyf 发表于 2020-9-18 05:31:36

如何用c语言体现进程地址空间

进程地址空间是操作系统为一个特定进程创建的一组可访问地址。众所周知,进程地址空间由文本/代码段,数据(已初始化和未初始化)段,堆栈和堆组成。在此作业中,要求您使用C语言编写程序,以探索如何将进程地址空间映射到内存中。

特别是,您的代码应至少有两个文件(.c)才能将多个目标文件合并为一个可执行目标文件,并且必须存在交叉引用。例如,文件1调用文件2中定义的函数。

在您的代码中,您应该想出一种方法来显示所有不同段的位置(如上所述),即起始/结束地址或位于指定段中的变量的地址。

在您的实现中回答以下问题:a)一个堆栈帧的大小是多少? b)代码段的起始地址是什么? c)您代码中每个函数的地址是什么? d)初始化的全局变量和未初始化的变量的地址是什么?

小白在线等求助 感谢大佬!!!!

zsyyf 发表于 2020-9-18 05:33:20

用c语言写代码

xieglt 发表于 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;
}

zsyyf 发表于 2020-9-18 11:49:18

xieglt 发表于 2020-9-18 10:26
本代码只适用于win32系统

为什么都用long, 用int可以吗?

xieglt 发表于 2020-9-18 11:53:30

zsyyf 发表于 2020-9-18 11:49
为什么都用long, 用int可以吗?

win32系统,int 和 long 是一样的

zsyyf 发表于 2020-9-18 12:07:35

xieglt 发表于 2020-9-18 11:53
win32系统,int 和 long 是一样的

感谢大佬
页: [1]
查看完整版本: 如何用c语言体现进程地址空间