我想在这里收集在Windows,Linux和OSX上运行可执行文件时会发生什么.特别是,我想完全理解操作的顺序:我的猜测是内核加载了可执行文件格式(PE,ELF或Mach-O)(但我忽略了ELF的各个部分(可执行文件和可链接格式)及其含义),然后你有动态链接器解析引用,然后__init运行可执行文件的部分,然后是main,然后是__fini,然后程序完成,但我确定它非常粗糙,也许是错的.
编辑:问题现在是CW.我正在填写linux.如果有人想为Win和OSX做同样的事情那就太棒了.
Way*_*yne 34
当然,这只是一个非常高的抽象层次!
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
Run Code Online (Sandbox Code Playgroud)
正如routeNpingme所说,寄存器设置在CPU内部并且魔术发生了!
更新:是的,我今天不能正确拼写!
Ste*_*ini 25
好的,回答我自己的问题.这将逐步完成,仅适用于Linux(也许是Mach-O).随意添加更多的东西到你的个人答案,以便他们得到投票(你可以获得徽章,因为它现在是CW).
我会中途开始,然后在我发现的时候建立其余部分.本文档使用x86_64,gcc(GCC)4.1.2.
在本节中,我们将描述从内核的角度调用程序时会发生什么,直到程序准备好执行.
_start在glibc中调用__libc_start_main(通过PLT)将以下信息传递给它
_init被调用
在 Windows 上,首先将图像加载到内存中。内核分析它将需要哪些库(读为“DLL”)并加载它们。
然后,它编辑程序映像以插入所需的每个库函数的内存地址。这些地址在 .EXE 二进制文件中已经有一个空格,但它们只是用零填充。
然后,每个 DLL 的 DllMain() 过程都会从最需要的 DLL 到最后一个逐个执行,就像遵循依赖关系的顺序一样。
一旦所有库都加载并准备就绪,最终映像就会启动,现在发生的任何事情都将取决于所使用的语言、所使用的编译器以及程序例程本身。
好吧,根据您的具体定义,您必须考虑 .Net 和 Java 等语言的 JIT 编译器。当您运行技术上不可“执行”的 .Net“exe”时,JIT 编译器会介入并编译它。