如何让 MSVC 将未初始化的数据放入 .bss?

Posted

技术标签:

【中文标题】如何让 MSVC 将未初始化的数据放入 .bss?【英文标题】:How do I get MSVC to put uninitialized data in .bss? 【发布时间】:2011-10-10 22:45:00 【问题描述】:

我正在使用自定义构建系统(在 Visual Studio 之外)构建 DLL,但我无法在 .bss 部分中显示未初始化的数据;编译器将其归为.data。这会使最终的二进制大小膨胀,因为它充满了巨大的零数组。

例如(示例中是 1KB 的小数组,但实际缓冲区要大得多):

int uninitialized[1024];
int initialized[1024] =  123 ;

编译器发出这样的程序集:

PUBLIC  _initialized
_DATA   SEGMENT
COMM    _uninitialized:DWORD:0400H
_initialized DD 07bH
    ORG $+4092
_DATA   ENDS

最终在目标文件中是这样的:

SECTION HEADER #3
   .data name
       0 physical address
       0 virtual address
    1000 size of raw data
     147 file pointer to raw data (00000147 to 00001146)
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
C0400040 flags
         Initialized Data
         8 byte align
         Read Write

(没有.bss 部分。)

当前编译标志:

cl -nologo -c -FAsc -Faobjs\ -W4 -WX -X -J -EHs-c- -GR- -Gy -GS- -O1 -Os -Foobjs\file.o file.cpp

我查看了http://msdn.microsoft.com/en-us/library/fwkeyyhe(v=vs.71).aspx 的选项列表,但没有发现任何明显的内容。

我正在使用 Visual Studio 2008 SP1 的编译器(Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86)。

【问题讨论】:

【参考方案1】:

你想使用__declspec(allocate()),你可以在这里阅读:http://msdn.microsoft.com/en-us/library/5bkb2w6t(v=vs.80).aspx

【讨论】:

【参考方案2】:

请注意,“原始数据大小”仅为 0x1000 或 4kB - 仅与初始化数组的大小完全相同。 .data 部分的 VirtualSize 将大于二进制映像中存储的实际数据的大小,并且未初始化的数组将占用松弛空间。使用 bss_seg pragma 将强制链接器将未初始化的数据放入它自己的单独部分。

【讨论】:

【参考方案3】:

如果您不担心便携性,可以尝试使用bss_seg pragma。

【讨论】:

以上是关于如何让 MSVC 将未初始化的数据放入 .bss?的主要内容,如果未能解决你的问题,请参考以下文章

反汇编Dis解析

内存段是如何划分的

将未初始化的内存传递给函数时如何断言/测试

BSS段数据段代码段堆与栈

了解 C 中数据 bss 段的大小命令

为啥需要 .bss 段?