[读书笔记]程序员的自我修养(6)

第六章 可执行文件的装载与进程

1. 启动参数将虚拟内存从2GB转到1GB,加入参数/3G
[boot loader]
timeout=2
default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS
[operating systems]
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional" /3G
/noexecute=optin /fastdetect

2. PAE(Physical Address Extension)
windows下AWE(Address Windowing Extensions)
linux下mmap()调用
XMS(extended memory specification)
windows下启动打开/PAE, /AWE

3. DSP,覆盖装入(利用时间换空间的方式):覆盖管理器Overlay Manager,树状结构,调用路径,禁止跨树间调用
页映射:FIFO算法,LUR算法

4. 进程建立
创立一个独立的虚拟空间
读取可执行文件(映像文件)头,并且建立虚拟空间与可执行文件的映射关系
将CPU的指令寄存器设置成可执行文件的入口地址,启动运行

5. ELF可执行文件的数据段和BSS段合并了,唯一区别是数据段从文件中初始化内容,而BSS段的内容全部初始化为0。

6. 堆向上扩展,栈向下扩展
随机地址空间分布技术
堆的最大申请数量:受操作系统的版本、程序本身的大小、用到的动态/共享库的数量大小、程序栈的数量大小等
#include <stdio.h>
#include <stdlib.h>
unsigned maximum = 0;
int main(int argc, char *argv[])
{
     unsigned blocksize[]={1024*1024, 1024, 1};
     int i, count;
     for(i=0; i<3; i++)
     {
          for(count=1; ; count++)
          {
               void *block=malloc(maximum+blocksize[i]*count);
               if(block)
               {
                   maximum=maximum+blocksize[i]*count;
                   free(block);
                }else
               {
                   break;
               }
          }
     }
     printf("maximum malloc size=5u bytes\n", maximum);
}

7. minibash
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
char buf[1024] = {0};
pid_t pid;
while (1)
{
   printf("minibash$");
   scanf("%s", buf);
   pid=fork();
   if (pid==0)
   {
    if (execlp(buf, 0)<0)
    {
     printf("exec error\n");
    }else if (pid>0)
    {
     int status;
     waitpid(pid, &status, 0);
    }else
     printf("fork error %d\n", pid);
   }
}
return 0;
}

8. ELF文件的装载问题
检查ELF可执行文件格式的有效性,比如魔数、程序头表中段的数量
寻找动态链接的“.interp”段,设置动态链接器的路径
根据ELF可执行文件的程序头表的描述,对ELF文件进行映射,比如代码、数据、只读数据
初始化ELF进程环境,比如进程启动时EDX寄存器的地址应该是DT_FINI的地址
将系统调用的返回地址修改成ELF可执行文件的入口点,这个入口点取决于程序的链接方式,对于静态链接的ELF可执行文件,这个程序入口点就是ELF文件的文件头中e_entry所指的地址;对于动态链接的ELF可执行文件,程序入口点是动态链接器

9. PE文件的装载过程
先读取文件的第一页,在这个页中,包含了DOS头、PE文件头和段表
检查进程地址空间中,目标地址是否可用,如果不可用,则另外选一个装载地址。这个问题对于可执行文件来说基本不存在,因为它往往是进程第一个装入的模块,所以目标地址不太可能被占用
使用段表中提供的信息,将PE文件中所有段一一映射到地址空间中相应的位置
如果装载地址不是目标地址,则进行rebasing
装载所有PE文件所需要的DLL文件
对PE文件中的所有导入符号进行解析
根据PE头中指定的参数,建立初始化堆和栈
建立主线程并且启动进程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值