gpt4 book ai didi

c# - 为什么代码中的小改动不会影响 exe 文件的大小?

转载 作者:太空狗 更新时间:2023-10-29 17:46:21 26 4
gpt4 key购买 nike

我很好奇 - 有时我会更改我的代码,重新编译,然后将我的 exe 或 dll 文件复制到旧版本上,然后看到 Windows 告诉我文件的日期已更改,但大小保持不变。这是为什么?

例如,我使用以下控制台应用程序进行了测试:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication4
{
class Program
{
static void Main(string[] args)
{
int a = 1;
int b = 2;
Console.WriteLine(a + b);
}
}
}

这生成了一个 5120 字节的 exe 文件(Visual Studio 2012,调试版本)。然后,我将代码更改为:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication4
{
class Program
{
static void Main(string[] args)
{
int a = 1;
int b = 2;
int c = 3;
Console.WriteLine(a + b + c);
}
}
}

exe的大小完全一样。

我查看了反汇编,它显示了 IL 代码中的差异,因此差异不可能被优化掉:

第一版:

.method private hidebysig static void  Main(string[] args) cil managed
{
.entrypoint
// Code size 15 (0xf)
.maxstack 2
.locals init (int32 V_0,
int32 V_1)
IL_0000: nop
IL_0001: ldc.i4.1
IL_0002: stloc.0
IL_0003: ldc.i4.2
IL_0004: stloc.1
IL_0005: ldloc.0
IL_0006: ldloc.1
IL_0007: add
IL_0008: call void [mscorlib]System.Console::WriteLine(int32)
IL_000d: nop
IL_000e: ret
} // end of method Program::Main

第二个版本:

.method private hidebysig static void  Main(string[] args) cil managed
{
.entrypoint
// Code size 19 (0x13)
.maxstack 2
.locals init ([0] int32 a,
[1] int32 b,
[2] int32 c)
IL_0000: nop
IL_0001: ldc.i4.1
IL_0002: stloc.0
IL_0003: ldc.i4.2
IL_0004: stloc.1
IL_0005: ldc.i4.3
IL_0006: stloc.2
IL_0007: ldloc.0
IL_0008: ldloc.1
IL_0009: add
IL_000a: ldloc.2
IL_000b: add
IL_000c: call void [mscorlib]System.Console::WriteLine(int32)
IL_0011: nop
IL_0012: ret
} // end of method Program::Main

如果代码在物理上更大,文件的大小怎么可能完全一样?这只是偶然的机会吗?它经常发生在我身上(在对代码进行小改动时)...

最佳答案

来自 https://msdn.microsoft.com/en-us/library/ms809762.aspx :

DWORD FileAlignment

In the PE file, the raw data that comprises each section is guaranteed to start at a multiple of this value. The default value is 0x200 bytes, probably to ensure that sections always start at the beginning of a disk sector (which are also 0x200 bytes in length). This field is equivalent to the segment/resource alignment size in NE files. Unlike NE files, PE files typically don't have hundreds of sections, so the space wasted by aligning the file sections is almost always very small.

编辑:磁盘上的所有部分大小都向上舍入(填充)为 FileAlignment 的倍数。来自 http://www.openwatcom.org/ftp/devel/docs/pecoff.pdf

SizeOfRawData

Size of the section (object file) or size of theinitialized data on disk (image files). For executableimage, this must be a multiple of FileAlignment fromthe optional header. If this is less than VirtualSizethe remainder of the section is zero filled. Becausethis field is rounded while the VirtualSize field is notit is possible for this to be greater than VirtualSize aswell. When a section contains only uninitialized data,this field should be 0.

我假设即使是最后一个部分也是如此填充,以便发出部分的链接器代码然后加载它们的加载器代码不必担心最后一个部分的大小的特殊情况。无论如何,修剪最后一部分将是一个毫无意义的优化,因为磁盘扇区(以及该文件系统的更大簇的顶部)有 internal fragmentation在大多数情况下,这会抵消任何此类“节省”(通过修剪最后一部分)。

关于c# - 为什么代码中的小改动不会影响 exe 文件的大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28059480/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com