一个程序的分析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/shuai1_1/article/details/82621210

一个程序的分析

int *array=(int *)malloc(0x1000); //在堆中分配1024字节内存空间
for(int i=0;i!=0x1000;++i)
    array[i]=1;

这是一个很简单的程序, 但背后的软硬件交互过程是怎样的呢?
1. 首先用户程序调用malloc函数,分配1024字节的内存空间, 返回一个虚地址(假设是0x450000).
2. 操作系统在进程的vma_struct链表中记录地址范围0x450000~0x451000为已分配地址空间, 并且是可读, 可写的.
3. 到此步时, 操作系统只是分配了一个地址范围, 该地址范围是虚拟地址范围, 虚拟地址不等于物理地址, 虚拟地址到物理地址还需要一个转换过程, 第二步所分配的地址空间不是真实分配的物理地址空间, 所以此时还未在进程的页表中建立页表项, TLB中也没有.
4. for(int i=0;i!=0x1000;++i) array[i]=1;, 用户程序写地址0x45000, 写的这个地址是虚拟地址, store(MIPS指令集结构)操作完成地址运算然后查找TLB, 然而TLB中没有此表项, 引起TLB refill异常.
5. TLB refill异常处理程序从相应的页表位置提取页表内容存储到TLB中去, 但此时这个地址空间的页表还没有初始化.
6. 异常处理程序返回到用户程序重新开始访问, TLB里面有对应的虚拟地址, 因为没有分配物理地址空间, 所以此时还是没有具体的物理地址, 此时又产生一个TLB valid异常
7. 产生TLB valid异常, 操作系统查找vma_struct, 发现该地址已经分配且处于可写状态, 此时操作系统才真正分配物理页面, 并分配物理页表, 将物理地址填入页表中, 更新TLB相应的表项, 此时写地址0x45000, TLB中有相应的页表项, store执行成功, 未产生异常

需要注意的是:
该程序分配的内存空间是1024字节, 而该系统一页正好为4k, 即1024字节, 故在对array[1~1023]的写过程中都不会发生TLB未命中异常.

参考书籍:
胡伟武<计算机体系结构基础>

猜你喜欢

转载自blog.csdn.net/shuai1_1/article/details/82621210
今日推荐