gpt4 book ai didi

.net - C# : why is DUMPBIN native code so different from Debug's Disassembly? 的反汇编

转载 作者:行者123 更新时间:2023-12-02 08:55:05 26 4
gpt4 key购买 nike

假设这是我的程序 simpleCsharp.exe:

namespace simpleCsharp
{
public class Program
{
public static int Main(string[] args)
{
uint x = 0xFEFEFE;
uint y = 0xEEEEEE;
uint z;
uint[] list = { 0, 1, 2, 4, 8 };
uint[] array = { 0xA, 0xB, 0xC, 0xD };
z = x + y + list[2] + array[1];
z = z - (y << 1);
return 0;
}
}
}

如果我在调试的反汇编窗口中查看简单 C# 程序的反汇编,native code输出至少有一定意义。例如,以下是 Debug 对 Main 的反汇编,并启用了优化:

uint x = 0xFEFEFE;
00000000 push ebp
00000001 mov ebp,esp
00000003 sub esp,28h
00000006 xor eax,eax
00000008 mov dword ptr [ebp-14h],eax
0000000b mov dword ptr [ebp-18h],eax
0000000e mov dword ptr [ebp-4],ecx
00000011 cmp dword ptr ds:[037D14ACh],0
00000018 je 0000001F
0000001a call 763B370F
0000001f xor edx,edx
00000021 mov dword ptr [ebp-0Ch],edx
00000024 xor edx,edx
00000026 mov dword ptr [ebp-1Ch],edx
00000029 xor edx,edx
0000002b mov dword ptr [ebp-20h],edx
0000002e xor edx,edx
00000030 mov dword ptr [ebp-8],edx
00000033 xor edx,edx
00000035 mov dword ptr [ebp-10h],edx
00000038 mov dword ptr [ebp-8],0FEFEFEh
uint y = 0xEEEEEE;
0000003f mov dword ptr [ebp-0Ch],0EEEEEEh
uint z;
uint[] list = { 0, 1, 2, 4, 8 };
00000046 mov edx,5
0000004b mov ecx,79882916h
00000050 call FD95FD70
00000055 mov dword ptr [ebp-24h],eax
00000058 lea ecx,[ebp-14h]
0000005b mov edx,37D25E0h
00000060 call 761A4716
00000065 lea eax,[ebp-14h]
00000068 push dword ptr [eax]
0000006a mov ecx,dword ptr [ebp-24h]
0000006d call 761A47F3
00000072 mov eax,dword ptr [ebp-24h]
00000075 mov dword ptr [ebp-1Ch],eax
uint[] array = { 0xA, 0xB, 0xC, 0xD };
00000078 mov edx,4
0000007d mov ecx,79882916h
00000082 call FD95FD70
00000087 mov dword ptr [ebp-28h],eax
0000008a lea ecx,[ebp-18h]
0000008d mov edx,37D25ECh
00000092 call 761A4716
00000097 lea eax,[ebp-18h]
0000009a push dword ptr [eax]
0000009c mov ecx,dword ptr [ebp-28h]
0000009f call 761A47F3
000000a4 mov eax,dword ptr [ebp-28h]
000000a7 mov dword ptr [ebp-20h],eax
z = x + y + list[2] + array[1];
000000aa mov eax,dword ptr [ebp-8]
000000ad add eax,dword ptr [ebp-0Ch]
000000b0 mov edx,dword ptr [ebp-1Ch]
000000b3 cmp dword ptr [edx+4],2
000000b7 ja 000000BE
000000b9 call 763B6900
000000be add eax,dword ptr [edx+10h]
000000c1 mov edx,dword ptr [ebp-20h]
000000c4 cmp dword ptr [edx+4],1
000000c8 ja 000000CF
000000ca call 763B6900
000000cf add eax,dword ptr [edx+0Ch]
000000d2 mov dword ptr [ebp-10h],eax
z = z - (y << 1);
000000d5 mov eax,dword ptr [ebp-0Ch]
000000d8 add eax,eax
000000da sub dword ptr [ebp-10h],eax
return 0;
000000dd xor eax,eax
000000df mov esp,ebp
000000e1 pop ebp
000000e2 ret

但是,如果我在同一个 C# 程序集上运行 DUMPBIN(调试信息 =“无”,因此它不只显示字节),即

dumpbin "simpleCsharp.exe" /disasm /out:"simpleCsharp_dump.txt"

生成文件中的 native 代码输出甚至与我在调试的反汇编中看到的内容不太相似。我在 dumpbin 的文件中甚至没有看到来自调试反汇编的任何指令或值。因此(上面)的两行 native 代码无处可寻。无论我在 Visual Studio (2010) 生成的程序集上运行 dumpbin 还是使用 ngen.exe ,都会出现这种情况。 生成原生镜像,并对原生镜像文件simpleCsharp.ni.exe运行dumpbin。

优化在“调试”中开启,并且build设置为“发布”,我运行“调试”的程序集与我提供给 ngen 的程序集之间的唯一区别是“调试信息”=“无”。

dumpbin simpleCsharp.ni.exe /disasm

以下是我在 native 镜像文件上运行 dumpbin 时对 simpleCsharp 程序的反汇编:

https://docs.google.com/leaf?id=0B9u9yFU99BOcYjNmNGRmNTItZjQ0NC00YmI0LWEyZTQtNjdkNDdhYTc2MmNm&hl=en

我至少希望看到数字 FEFEFE 或 EEEEEE 显示在 dumpbin 的输出中的某个位置,并且它确实显示在调试反汇编中。

有人可以解释一下为什么我在 native 镜像文件的 dumpbin 输出中看不到同一个程序的 一行 行 Debug 反汇编代码吗?如果是因为优化,您介意提供一些细节吗?

谢谢

最佳答案

您忘记了即时编译器。程序集不包含机器代码,它是在运行时由程序集中的 IL 的抖动生成的。您可以使用 ildasm.exe 或 Reflector 等工具查看程序集中的 IL。 Dumpbin.exe 支持很差,它可以转储 CLR header ,仅此而已。

请注意,ngen-ed 图像包含通过抖动优化的机器代码。该优化器极大地改变了机器代码。调试器中的优化默认处于关闭状态。要查看它,您必须调试发布版本并更改调试器选项。工具+选项、调试、常规,取消选中“抑制模块加载时的 JIT 优化”选项。另请注意,生成的代码可能在某些地方完全不同,因为它是预编译的而不是即时编译的。抖动可以做得更好,因为它具有预先无法获得的知识。

关于.net - C# : why is DUMPBIN native code so different from Debug's Disassembly? 的反汇编,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5539204/

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