当你运行一个程序时会发生什么?
我想在这里收集当您在Windows,Linux和OSX上运行可执行文件时会发生什么情况。 特别是,我想正确理解操作的顺序:我的猜测是可执行文件格式(PE,ELF或Mach-O)是由内核加载的(但我忽略了ELF的各个部分(可执行文件和Linkable Format)及其含义),然后你有动态链接器来解析引用,然后运行可执行文件的__init
部分,然后是main,然后是__fini
,然后程序就完成了,但我确定它是非常粗糙,可能是错误的。
编辑:现在的问题是CW。 我正在填补Linux。 如果有人想为Win和OSX做同样的事情,那就太好了。
这当然是非常高和抽象的水平!
Executable - No Shared Libary:
Client request to run application
->Shell informs kernel to run binary
->Kernel allocates memory from the pool to fit the binary image into
->Kernel loads binary into memory
->Kernel jumps to specific memory address
->Kernel starts processing the machine code located at this location
->If machine code has stop
->Kernel releases memory back to pool
Executable - Shared Library
Client request to run application
->Shell informs kernel to run binary
->Kernel allocates memory from the pool to fit the binary image into
->Kernel loads binary into memory
->Kernel jumps to specific memory address
->Kernel starts processing the machine code located at this location
->Kernel pushes current location into an execution stack
->Kernel jumps out of current memory to a shared memory location
->Kernel executes code from this shared memory location
->Kernel pops back the last memory location and jumps to that address
->If machine code has stop
->Kernel releases memory back to pool
JavaScript/.NET/Perl/Python/PHP/Ruby (Interpretted Languages)
Client request to run application
->Shell informs kernel to run binary
->Kernel has a hook that recognises binary images needs a JIT
->Kernel calls JIT
->JIT loads the code and jumps to a specific address
->JIT reads the code and compiles the instruction into the
machine code that the interpretter is running on
->Interpretture passes machine code to the kernel
->kernel executes the required instruction
->JIT then increments the program counter
->If code has a stop
->Jit releases application from its memory pool
正如routeNpingme所说的那样,寄存器被设置在CPU内部并发生奇迹!
更新:是的,我今天无法正确使用!
好的,回答我自己的问题。 这将逐步完成,并且只针对Linux(也许Mach-O)。 随意添加更多的东西给你的个人答案,让他们得到upvoted(你可以得到徽章,因为它现在是CW)。
我会中途开始,并且根据我的发现建立其余的部分。 本文档是使用x86_64,gcc(GCC)4.1.2编写的。
打开文件,初始化
在本节中,我们描述从内核的角度调用程序时发生的情况,直到程序准备好执行。
程序的执行
_start调用glibc中的__libc_start_main(通过PLT),将以下信息传递给它
_init被调用
在Windows上,首先将图像加载到内存中。 内核分析它将要求的哪些库(读取“DLL”)并加载它们。
然后编辑程序映像以插入它所需的每个库函数的内存地址。 这些地址已经在.EXE二进制文件中有一个空格,但它们只填充了零。
然后每个DLL的DllMain()过程从最需要的DLL到最后一个被逐个执行,就像依赖关系的顺序一样。
一旦所有库加载完毕并准备就绪,最终图像就会启动,现在发生的任何事情都将取决于所使用的语言,所使用的编译器以及程序例程本身。
链接地址: http://www.djcxy.com/p/67775.html