CRT初始化 (参考自MSDN)

本文详细介绍了CRT如何初始化全局状态,包括CRT库如何通过链接器提供的函数指针列表来调用全局初始化器的过程。此外还深入探讨了编译器如何生成动态初始化器以及链接器如何组织这些初始化器。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CRT Initialization

    This topic describes how the CRT initializes global states in native code.

    By default, the linker includes the CRT library, which provides its own startup code. This startup code initializes the CRT library, calls global initializers, and then calls the user-provided main function for console applications.

 

Initializing a Global Object

 

Consider the following code:

 

int func(void)

{

    return 3;

}


int gi = func();


int main()

{

    return gi;

}


 

    According to the C/C++ standard, func() must be called before main() is executed.But who calls it?

    One way to determine this is to set a breakpoint in func(),debug the application, 

and examine the stack.This is possible because the CRT source code is included with Visual Studio.

     

    When you browse the functions on the stack, you will find that the CRT is looping through a list of function pointers and calling each one as it encounters them.These functions are either similar to func() or constructors for class instances.

 

   The CRT obtains the list of function pointers from the Visual C++ compiler.When the compiler sees a global initializer, it generates a dynamic initializer in the .CRT$XCU section (where CRT is the section name and XCU is the group name).To obtain a list of those dynamic initializers run the command dumpbin /all main.obj, and then search the .CRT$XCU section (when main.cpp is compiled as a C++ file, not a C file).It will be similar to the following:

 

SECTION HEADER #6

.CRT$XCU name

       0 physical address

       0 virtual address

       4 size of raw data

     1F2 file pointer to raw data (000001F2 to 000001F5)

     1F6 file pointer to relocation table

       0 file pointer to line numbers

       1 number of relocations

       0 number of line numbers

40300040 flags

         Initialized Data

         4 byte align

         Read Only


RAW DATA #6

  00000000: 00 00 00 00                                      ....


RELOCATIONS #6

                                                Symbol    Symbol

 Offset    Type              Applied To         Index     Name

 --------  ----------------  -----------------  --------  ------

 00000000  DIR32                      00000000         C  ??__Egi@@YAXXZ (void __cdecl `dynamic initializer for 'gi''(void))


  The CRT defines two pointers:

         __xc_a in .CRT$XCA

         __xc_z in .CRT$XCZ

 

     

  Both groups do not have any other symbols defined except __xc_a and __xc_z.Now, when the linker reads various .CRT groups, it combines them in one section and orders them alphabetically.This means that the userdefined global initializers (which the Visual C++ compiler puts in .CRT$XCU) will always come after .CRT$XCA and before .CRT$XCZ.

 

   The section will resemble the following:

.CRT$XCA

            __xc_a

.CRT$XCU

            Pointer to Global Initializer 1

            Pointer to Global Initializer 2

.CRT$XCZ

            __xc_z


 

   So, the CRT library uses both __xc_a and __xc_z to determine the start and end of the global initializers list because of the way in which they are laid out in memory after the image is loaded.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值