linux0.11之creat_tables()

     在了解creat_tables()这个函数之前,我想先要明白他上面的几个p值是什么,在do_execve()中定义:

unsigned long p = PAGE_SIZE*MAX_ARG_PAGES-4;  //P指向参数和环境变量的最后部

      其次336,,337行上的p值是128kb参数和环境变量空间中的偏移值:

p = copy_srtings(envc,envp,page,p,0);
     再向下看就是364,和365
p+ = change_ldt(ex,a_text,page); //返回段限长
p- = LIBRARY_SIZE + MAX_ARG_PAGES*PAGE_SIZE;

    这两行中,第一行返回数据段的长度:64M,得到这个长度然后再与上面的p值(偏移量)相加,再减去库文件和128KB的参数和环境变量值(例如:p的偏移值为128kb-34,则:p = 128kb-34b + 64M - 4M - 128kb = 60M-34b),于是p被调整为从进程逻辑地址空间开始算起的参数和环境变量起始指针。(为什么要用逻辑地址,我们往下看大笑

       进入creat_tables()函数:

sp = (unsigned long *)(0xfffffffc & (unsigned long) p);
sp -=  envc +1;
envp = sp;
sp -= argc+1;
argv = sp;
put_fs_long((unsigned long)envp,--sp);
put_fs_long((unsigned long)argv,--sp);
put_fs_long((unsinned long)argc,--sp);

       下面这个图很好的反应了上面的代码:      

             

       下面我们来分析一下put_fs_long()这个函数(segment.h):

put_fs_long(unsigned long val,unsigned long *addr)
{
  _asm_ ("movw %0,%%fs:%1"::"r"(val),"m"(*addr));
}
       我认为这个函数就是我们上面使用逻辑地址的原因,这个函数已经设置好了段选择子,fs指向局部数据段描述符,取段描述符中的线性基地址,再拿这个线性基地址加上偏移量,最后形成一个线性地址:

                

        拿进程2来说,线性基地址被设置成128M,所以线性地址就是128M+60M-34了,val也会被设置到这个线性地址处。

        就是指针的对应关系了,不说了,睡了











   

   

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值