c# - C# 64 位发布代码的反汇编 View 比 32 位调试代码长 75%?

标签 c# assembly compiler-construction visual-studio-2012 disassembly

编辑

我测试了32位版本,代码紧凑。因此以下是 64 位问题。


我正在使用 VS 2012 RC。 Debug是32位的,Release是64位的。下面是一行代码的调试发布反汇编:

         crc = (crc >> 8) ^ crcTable[((val & 0x0000ff00) >> 8) ^ crc & 0xff];
0000006f  mov         eax,dword ptr [ebp-40h] 
00000072  shr         eax,8 
00000075  mov         edx,dword ptr [ebp-3Ch] 
00000078  mov         ecx,0FF00h 
0000007d  and         edx,ecx 
0000007f  shr         edx,8 
00000082  mov         ecx,dword ptr [ebp-40h] 
00000085  mov         ebx,0FFh 
0000008a  and         ecx,ebx 
0000008c  xor         edx,ecx 
0000008e  mov         ecx,dword ptr ds:[03387F38h] 
00000094  cmp         edx,dword ptr [ecx+4] 
00000097  jb          0000009E 
00000099  call        6F54F5EC 
0000009e  xor         eax,dword ptr [ecx+edx*4+8] 
000000a2  mov         dword ptr [ebp-40h],eax
-----------------------------------------------------------------------------
         crc = (crc >> 8) ^ crcTable[((val & 0x0000ff00) >> 8) ^ crc & 0xff];
000000a5  mov         eax,dword ptr [rsp+20h] 
000000a9  shr         eax,8 
000000ac  mov         dword ptr [rsp+38h],eax 
000000b0  mov         rdx,124DEE68h 
000000ba  mov         rdx,qword ptr [rdx] 
000000bd  mov         eax,dword ptr [rsp+00000090h] 
000000c4  and         eax,0FF00h 
000000c9  shr         eax,8 
000000cc  mov         ecx,dword ptr [rsp+20h] 
000000d0  and         ecx,0FFh 
000000d6  xor         eax,ecx 
000000d8  mov         ecx,eax 
000000da  mov         qword ptr [rsp+40h],rdx 
000000df  mov         rax,qword ptr [rsp+40h] 
000000e4  mov         rax,qword ptr [rax+8] 
000000e8  mov         qword ptr [rsp+48h],rcx 
000000ed  cmp         qword ptr [rsp+48h],rax 
000000f2  jae         0000000000000100 
000000f4  mov         rax,qword ptr [rsp+48h] 
000000f9  mov         qword ptr [rsp+48h],rax 
000000fe  jmp         0000000000000105 
00000100  call        000000005FA5D364 
00000105  mov         rax,qword ptr [rsp+40h] 
0000010a  mov         rcx,qword ptr [rsp+48h] 
0000010f  mov         ecx,dword ptr [rax+rcx*4+10h] 
00000113  mov         eax,dword ptr [rsp+38h] 
00000117  xor         eax,ecx 
00000119  mov         dword ptr [rsp+20h],eax

64 位版本中所有额外代码的作用是什么?它在测试什么?我没有对此进行基准测试,但 32 位代码的执行速度应该快得多。

编辑

整个函数:

public static uint CRC32(uint val)
{
    uint crc = 0xffffffff;

    crc = (crc >> 8) ^ crcTable[(val & 0x000000ff) ^ crc & 0xff];
    crc = (crc >> 8) ^ crcTable[((val & 0x0000ff00) >> 8) ^ crc & 0xff];
    crc = (crc >> 8) ^ crcTable[((val & 0x00ff0000) >> 16) ^ crc & 0xff];
    crc = (crc >> 8) ^ crcTable[(val >> 24) ^ crc & 0xff];

    // flip bits
    return (crc ^ 0xffffffff);
}

最佳答案

我怀疑您在调试发布版本时使用“Go to disassembly”来获取汇编代码。

在转到“工具”->“选项”、“调试”、“常规”并禁用“在模块加载时抑制 JIT 优化”后,我得到了一个没有错误检查的 x64 程序集列表。

似乎默认情况下,即使在 Release模式下,如果附加了调试器,代码也不会优化。在尝试对代码进行基准测试时请记住这一点。

PS:基准测试显示 x64 比 x86 稍快,10 亿次函数调用分别为 4.3 秒和 4.8 秒。

编辑:断点对我仍然有效,否则取消选中后我将无法看到反汇编。上面的示例行看起来像这样 (VS 2012 RC):

crc = (crc >> 8) ^ crcTable[((val & 0x0000ff00) >> 8) ^ crc & 0xff];
00000030  mov         r11d,eax 
00000033  shr         r11d,8 
00000037  mov         ecx,edx 
00000039  and         ecx,0FF00h 
0000003f  shr         ecx,8 
00000042  movzx       eax,al 
00000045  xor         ecx,eax 
00000047  mov         eax,ecx 
00000049  cmp         rax,r9 
0000004c  jae         00000000000000A4 
0000004e  mov         eax,dword ptr [r8+rax*4+10h] 
00000053  xor         r11d,eax 

关于c# - C# 64 位发布代码的反汇编 View 比 32 位调试代码长 75%?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12397108/

相关文章:

c++ - 为什么 int 在 64 位编译器上通常是 32 位?

compiler-construction - 手工创建的 OCaml AST 的无限值(value)

c# - 如何优先于 IHttpHandler 的 Web Api Controller ?

C#、WPF、将 List<string> 绑定(bind)到 DataGrid

c# - 将 REST Web API 应用程序与 SignalR 集成?

linux - 在 ARM 上编写操作系统时,如何像在 x86 中一样实现基本的 I/O 功能?

c++ - 在VS2010中排除一个系统头文件

c# - 我能否实现一个接口(interface),该接口(interface)包含接口(interface)所需的子类型的属性?

c++ - 图形驱动程序如何以编程方式从 CPU 到 GPU 进行通信?

assembly - 汇编代码中的返回地址