返回首页 - 搜索更多 -
主  题:
有谁能讲讲 一个EXE 文件是怎样被WINDOWS 给执行的,比如它是怎么被加载的,是怎么被装入内存的,CPU是怎么处理的。


回复人: fz_zhou(vcfan) ( ) 信誉:99 2001-07-31 14:27:12Z 得分:0
?

去看看汇编再学一下计算机原理你会懂一点的!
windows程序设计这本书对你也会有不少的帮助!
Top
回复人: han012(阿毛) ( ) 信誉:98 2001-07-31 14:29:16Z 得分:0
?

在<<深入浅出>>一书中,候先生对一个进程从诞生到死亡的流程进行了简单的阐述。虽然只有十几点,但对于初学者来说,能够完全理解其中的含义已经不是一件易事了。总结自己的一些经验,对候先生的阐述进行了一些扩充,希望对初学者有所帮助,也希望高手指正其中的错误或不妥之处。

**************************************************
我对一个PROCESS (例App.exe)的诞生/死亡的理解:

1.Shell调用CreateProcess启动App.exe

2.系统产生一个“进程核心对象”,计数值为1

3.系统分配4GB进程空间

4.系统载入器(loader)将EXE文件映象和所有需要隐式加载的DLL文件映象映射到进程地址空间中。在此期间,要完成模块基址重定位, IAT(import address table)表转向,并且分配EXE及DLL中的全局和静态变量空间。注意只是分配空间,并没有执行初始化(包括执行C++对象的构造函数,已初始化数据除外)。下表给出了一些常见的节名和内容

节名(Segment) 内容
.text 应用程序或DLL的代码
.bss 未初始化的数据
.rdata 只读的运行时数据
.rsrc 资源
.edata 输出名字表
.data 初始化的数据
.xdata 异常处理表
.idata 引入名字表
.CRT 只读的C运行时数据
.reloc 修正表信息
.debug 调试信息
.tls 线程局部存储

5.系统创建了进程的主线程(primary thread)

6.主线程为每个DLL调用_DLLMainCRTStartu() 函数。
当链接DLL时,链接器在生成的DLL文件映象中嵌入了DLL的进入/退出函数的地址。缺省时为,链接器假设进入函数名为:_DLLMainCRTStartup。该函数包含在C运行时库文件中,当链接DLL时被静态的链接到DLL文件的映象中。即使使用的是C运行时库的DLL版本,该函数也会被静态的链接。
当DLL文件被映射到进程地址空间时,系统实际调用的是该函数_DLLMainCRTStartup, 而不是你的DLLMain函数。该函数执行:
a.初始化C运行时库。
// Do runtime startup initializers.
_initterm( &__xi_a, &__xi_z );
b.确保收到DLL_PROCESS_ATTACH通知时,DLL的所有全局或静态C++对象都被初始化。
(调用C++对象的Constructor函数)
// Do C++ constructors (initializers) specific to this DLL
_initterm( &__xc_a, &__xc_z );
c.完成初始化后,该函数调用你的DLLMain函数。
retcode = DllMain(hDllHandle, dwReason, lpreserved);

7.主线程根据EXE文件中的子系统值GUI/(CUI),执行WinMainCRTStartup/(MainCRTStartup)
a.得到一个新进程的全部命令行的指针。
b.得到一个新进程的环境变量指针。
c.通过STDLIB.H来初始化能被应用访问的C运行时全局变量。例
_osver, _winmajor, _winminor, _winver, _argc, _argv, _environ.
// Do runtime startup initializers.
_initterm( __xi_a, __xi_z );
d.执行EXE的全局或静态C++对象的构造函数(初始化)。
// Do C++ constructors (initializers) specific to this EXE
_initterm( __xc_a, __xc_z );
c.调用WinMain函数。
mainret = WinMain(
          GetModuleHandle(NULL), //EXE映象文件基地址
              NULL,
            lpszCommandLine,
              StartupInfo.dwFlags & STARTF_USESHOWWINDOW
? StartupInfo.wShowWindow: SW_SHOWDEFAULT
            );

8.至此,主线程启动工作完成,执行进入WinMain() 。在WinMain() 中执行MFC的消息循环,驱动主线程运行,直至消息循环终止。

--------------------------------
以下为退出过程

9.主线程继续WinMainCRTStartup() 执行exit(mainret)-> doexit()函数。执行一些清理工作。
a.除主线程外,锁其它线程。Makes sure only one thread is in the exit code at a time.
#ifdef _MT //多线程
_lockexit(); // assure only 1 thread in exit path
#endif
b.执行EXE中全局或静态C++对象的析构函数,在doexit() 中。例 MyApp::~MyApp()
c.对应于启动过程中通过STDLIB.H来初始化能被应用访问的C运行时全局变量,要执行清理工作
do pre-terminators,do terminators
d.调用ExitProcess(uExitCode) 
终止除主线程之外的所有未结束的其它线程(包括在DLL中启动的线程)。由于调用ExitProcess() 而被强制终止的线程将造成内存泄漏。所以应在此之前的适当地方正确结束所有其它线程。
为每个DLL调用_DllMainCRTStartup() ,当所有DLL的DLLMain() 执行后,终止进程。

其中_DllMainCRTStartup(被ExitProcess()调用)中执行
a.调用你的DLL的DLLMain()函数,REASON为DLL_PROCESS_DETACH
b.调用_CRT_INIT() 函数 ,执行DLL中全局或静态C++对象的析构函数。例 MyDll::~MyDll()



Top
回复人: younker() ( ) 信誉:97 2001-07-31 14:29:38Z 得分:0
?

看看<<深入浅出MFC>>应该就可以了。

Top
回复人: imhua(华弟) ( ) 信誉:100 2001-07-31 14:38:01Z 得分:0
?

最好是要了解windows里的可执行文件的结构。
在罗云彬的编程乐园(http://bigluo.tz163.net/home.htm)里有PE类型文件的教程!
Top
回复人: Kevin_qing() ( ) 信誉:103 2001-07-31 14:44:54Z 得分:0
?

厉害······
Top
回复人: greensleeve(绿袖子) ( ) 信誉:91 2001-07-31 14:46:50Z 得分:0
?

perfectly
Top
回复人: ExitWindows(void) ( ) 信誉:97 2001-07-31 19:32:59Z 得分:0
?

up
Top
回复人: lttltgr(小虎子) ( ) 信誉:99 2001-07-31 20:07:37Z 得分:0
?

up
Top
回复人: ExitWindows(void) ( ) 信誉:97 2001-08-01 00:26:49Z 得分:0
?

up
Top
回复人: ExitWindows(void) ( ) 信誉:97 2001-08-01 03:57:02Z 得分:0
?

up
Top

结贴