4.4 模块初始化与结束化

4.4.1模块入口代码
  编译器为每个Delphi模块(可执行程序、动态链接库或包)生成模块入口代码。同类型的程序或模块,其入口代码是相同的。
  编译器为可执行程序.EXE)生成的入口代码为:

Project1.dpr.9:begin
0044CA9855push      ebp
0044CA99 8BEC       mov ebp,esp
0044CA9B 83C4F0      add esp,-$10
0044CA9EB8B8C84400    mov eax,$0044c8b8//传入单元初始化表地址
0044CAA3 E80080FBFF   cal10InitExe //调用模块初始化例程

  为动态链接库(.DLL)生成的入口代码为:

Project2.dpr.19:begin
00B81FD4 55        push ebp
00B81FD5 8BEC        mov ebp,esp
00B81FD7 83C4C4add    esp,-$3c
00B81FDA B85C1FB800   mov eax,$00b81f5c//传入单元初始化表地址
00B81FDP E8F435FFEF   call InitLib //调用模块初始化例程

  为包(.BPL)生成的入口代码为:

Packagel.dpk.33:end,
//跳转到模块初始化例程,是一个相对寻址的短跳转
04A512B0 E9C3FEFFFF imp eInitPkg

  除了包之外,入口代码都主要负责传入单元初始化表的地址。其后的所有初始化工作,全部交由System.pas中的模块初始化例程完成。这些例程分别是:

//define in SysInit. pas
procedure _InitLib;
procedure _InitExe(InitTable: Pointer);
function InitPkg(Hinst: Integer; Reason: Integer;Resvd: pointer): LongBool; stdcall;

4.4.2编译器决定的程序执行流程

  编译器总是按照固定的流程和代码来生成项目的二进制文件。例如一个简单的项目:

Drogram GuiProg;
uses
    Dialogs;
begin
    ShowMessage(‘ Test‘);
end.

  它编译的代码为:

GuiProg. dpr.4:begin
00451F5C 55push     ebp
00451F5D 8BEC      mov ebp, esp
00451F5F 83C4F0     add esp,-$10
00451F62 B8841D4500    mov eax,$00451d84
00451F67 E8F43CFBFF    ca11 eInitExe
GuiProg. dpr.5:ShowMessage(‘ Test‘);
00451F6C B8841F4500   mov eax,$00451f84
00451F71 E8D2FBFFFF    call ShowMessage
Guiprog.dpr.6:end.
00451F76 E8E11DFBFF   call eHalt0

  上面的汇编代码是顺序执行的,编译器只是在这个流程的结尾加入了一行“call
  @Halt0”。Delphi并没有刻意为模块准备结束化代码或者指定结束化代码的地址,它只须按照这样的方式来编译即可。
  对于可执行程序(.EXE)来说,用户在项目文件(.DPA)的begin..end之间加入的代码决定了其所有的功能,而编译器只是把.DPR文件按照.EXE方式生成,并将用户编写的代码编译成二进制代码,放到入口代码和结束时的“[email protected]”之间。
  其他类型的文件与可执行程序并不一致。在下一章“面向Windows开发的基本实现”中,将详细地讲述所有的模块初始化与结束化例程,以及它们不同执行流程。

原文地址:https://www.cnblogs.com/YiShen/p/9884797.html

时间: 2024-10-09 00:17:58

4.4 模块初始化与结束化的相关文章

Framebuffer 驱动学习总结(二)---- Framebuffer模块初始化

---恢复内容开始--- Framebuffer模块初始化过程:--driver\video\fbmem.c 1.  初始化Framebuffer: FrameBuffer驱动是以模块的形式注册到系统中,在模块初始化时,创建FrameBuffer对应的设备文件及proc文件,并注册FrameBuffer设备操作接口函数fb_fops. static int __init fbmem_init(void) { proc_create("fb", 0, NULL, &fb_proc

Nginx 中 HTTP模块初始化

概述 在前面的文章< Nginx 配置解析>简单讲解了通用模块的配置项解析,并且大概讲解了HTTP 模块的配置项解析过程,本文更具体的分析 HTTP 模块的初始化过程.HTTP 模块初始化过程主要有:上下文结构初始化.配置项解析.配置项合并.server 相关端口设置. HTTP 模块接口 ngx_http_module_t 结构体 在 Nginx 中,结构体 ngx_module_t 是 Nginx 模块最基本的接口.对于每一种不同类型的模块,都有一个具体的结构体来描述这一类模块的通用接口.

nginx源码分析之模块初始化

在nginx启动过程中,模块的初始化是整个启动过程中的重要部分,而且了解了模块初始化的过程对应后面具体分析各个模块会有事半功倍的效果.在我看来,分析源码来了解模块的初始化是最直接不过的了,所以下面主要通过结合源码来分析模块的初始化过程. 稍微了解nginx的人都知道nginx是高度模块化的,各个功能都封装在模块中,而各个模块的初始化则是根据配置文件来进行的,下面我们会看到nginx边解析配置文件中的指令,边初始化指令所属的模块,指令其实就是指示怎样初始化模块的. 模块初始化框架 模块的初始化主要

跟厂长学PHP7内核(五):一步步分析生命周期之模块初始化阶段

上篇我们讲到了模块初始化阶段,并得知它是由php_module_startup函数来实现的.该阶段的主要作用是初始化变量.常量:注册各种函数,比如工具.词法.语法函数等:解析配置文件:加载扩展:当然最重要的是计算出PHP二进制程序的路径,现在让我们来研究一下该函数都做了哪些工作. 1.sapi_initialize_request_empty函数 // main/SAPI.c SAPI_API void sapi_initialize_empty_request(void) { SG(serve

C# 9 提案:模块初始化器

模块初始化器提案已经被提升到 C# 9 候选资格.它就像 C#中的静态构造函数,但不是应用于一个类,而是应用于整个程序集. 这个特性从一开始就存在于 CLR 中,但是直到现在还没有被 C#公开.根据模块初始化器提案,它将作为对静态构造函数语法的修改而公开. 复制代码   [module: ModuleInitializer(typeof(MyModuleInitializer))]   internal static class MyModuleInitializer   {   static

Nginx的源码结构和模块初始化

前言: 上一篇(http://blog.csdn.net/xlgen157387/article/details/49781487)已经介绍了Nginx的基本功能,也介绍了在Windows下的安装和简单的实现负载均衡,下边主要学习一下Nginx的源码结构. Nginx的源码src目录结构(未进行编译安装) 环境:nginx-1.8.0+CentOS7.0 (可以使用yum install tree来安装tree命令,就可以显示出文件的树结构) [[email protected] nginx-1

ABP中的模块初始化过程(一)

在总结完整个ABP项目的结构之后,我们就来看一看ABP中这些主要的模块是按照怎样的顺序进行加载的,在加载的过程中我们会一步步分析源代码来进行解释,从而使自己对于整个框架有一个清晰的脉络,在整个Asp.Net Core项目中,我们启动一个带Swagger UI的Web API项目为例,在介绍这个Web API项目之前我们先来看看整个Swagger 文档的样式. 我们定义的WebAPI最终都会以Swagger文档这种形式来展现出来,通过这种形式也是非常方便我们进行代码的调试的,在进行网站的前后端分离

ABP中模块初始化过程(二)

在上一篇介绍在StartUp类中的ConfigureService()中的AddAbp方法后我们再来重点说一说在Configure()方法中的UserAbp()方法,还是和前面的一样我们来通过代码来进行一步步分析. public static class AbpApplicationBuilderExtensions { public static void UseAbp(this IApplicationBuilder app) { app.UseAbp(null); } public sta

Linux netfilter 学习笔记 之十一 ip层netfilter的NAT模块初始化以及NAT原理

1.NAT的原理 NAT会修改数据包的ip层的源或者目的ip地址.在实际应用中,NAT 主要用于实现私有网络访问公共网络的功能. 1.1 SNAT 源目的地址转换,即对ip数据包的源ip地址进行转换操作,典型的应用即是网关,网关的lan侧会下挂至少两台设备,而这两台设备的ip地址都是lan侧地址,而lan侧设备又要访问公网,这就需要SNAT大展身手了,通过将lan侧发送的ip数据包的源ip地址转换成公网地址即可以访问公网了. 1.2 DNAT 目的地址转换主要是将ip数据包的目的ip地址进行修改