一个内存寻址的例子

来源:互联网 发布:淘宝客采集软件是什么 编辑:程序博客网 时间:2024/05/17 09:41
     在main函数中调用了一个简单的函数greeting(),假设编译连接之后的greeting的地址是0X08048568。下面具体阐述了对这个逻辑地址寻址的过程:(针对Intel X86 + linux)
     1、转化为线性地址
     因为是代码段,所以从寄存器CS中取index。在进程运行初始,CS被赋值0X23,即index=4,TI=0(GDT表),RPL=3(用户权限)。在linux中,用户进程只使用GDT表。
     根据index=4,在GDT表的第4项找到8字节地址描述项,也是程序运行初始设定的(2-5项):
     K_CS: 0000 0000 1100 1111 1001 1010 0000 0000 0000 0000 0000 0000 1111 1111 1111 1111
     K_DS: 0000 0000 1100 1111 1001 0010 0000 0000 0000 0000 0000 0000 1111 1111 1111 1111
     K_CS: 0000 0000 1100 1111 1111 1010 0000 0000 0000 0000 0000 0000 1111 1111 1111 1111
     K_DS: 0000 0000 1100 1111 1111 0010 0000 0000 0000 0000 0000 0000 1111 1111 1111 1111
     所以,现在使用的地址是第4项 K_CS: 0000 0000 1100 1111 1111 1010 0000 0000 0000 0000 0000 0000 1111 1111 1111 1111。 其中基地址的32位全部为0,所以0+逻辑地址(偏移量)= 逻辑地址。从而得到了线性地址。
 
     2、从线性地址到物理地址
     CR3(作为页面表基地址)在程序运行初始的时候设定,此时,将线性地址展开
     0000 1000 0000 0100 1000 0101 0110 1000
     取高10位作为页面表(表项作为目录表基地址)下标,中间10位作为目录项(表项作为内存表基地址)下标,最后12位作为内存偏移。
     从而最后得到了物理地址。
     其中,页面表项和目录项中32位地址,仅有高20位使用,低12位用作功能位。因为4k对齐。
 
原创粉丝点击