c# - 划分/移动 assembly 差异

标签 c# assembly

早上好,下午好,晚上好,

在查看关闭“抑制 JIT 优化 (...)”选项的调试版本的汇编代码时,我注意到以下奇怪的行为(bitCountulong):

          int BitQuotient = (int)(bitCount / 32);

00000110  push        dword ptr [ebp+0Ch] 
00000113  push        dword ptr [ebp+8] 
00000116  push        0 
00000118  push        20h 
0000011a  call        738EF4D5 
0000011f  mov         dword ptr [ebp-44h],eax 

相对于

          int BitQuotient = (int)(bitCount >> 5);

00000110  mov         eax,dword ptr [ebp+8] 
00000113  mov         edx,dword ptr [ebp+0Ch] 
00000116  shrd        eax,edx,5 
0000011a  shr         edx,5 
0000011d  mov         dword ptr [ebp-44h],eax 

为什么组装会有这么大的差异?难道编译器不应该检测到除以 32 与右移 5 相同并替换代码吗?另外,call 指令对第一段代码做了什么?我怀疑这与应用于非 native ulong 的运算符 / 有关,但这也意味着编译器不会内联此类运算符?

编辑:看看 int BitRemainder = (int)(bitCount % 32) 而不是 int BitRemainder = (int)(bitCount & 31) ):

00000120  mov         eax,dword ptr [ebp+8] 
00000123  mov         edx,dword ptr [ebp+0Ch] 
00000126  mov         ecx,20h 
0000012b  cmp         edx,ecx 
0000012d  jb          00000139 
0000012f  mov         ebx,eax 
00000131  mov         eax,edx 
00000133  xor         edx,edx 
00000135  div         eax,ecx 
00000137  mov         eax,ebx 
00000139  div         eax,ecx 
0000013b  mov         eax,edx 
0000013d  xor         edx,edx 
0000013f  mov         dword ptr [ebp-48h],eax 

00000120  mov         eax,dword ptr [ebp+8] 
00000123  and         eax,1Fh 
00000126  mov         dword ptr [ebp-48h],eax 

非常感谢。

最佳答案

第一个代码片段中的代码执行 64 位除法。 x86 抖动不会为该内联生成机器代码,它会太多。它依赖于名为 JIT_ULDiv 的辅助函数。这是针对抖动或 C 编译器的常见策略。您可以在 SSCLI20 源代码 clr/src/vm/jithelpers.cpp 源代码文件中看到抖动可以使用的辅助函数类型。 long 和 ulong 算术的辅助函数位于文件顶部。

第二个片段进行 32 位除法,需要内联生成足够少的机器代码指令。将除法转换为移位是一个简单的优化。

关于c# - 划分/移动 assembly 差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5389151/

相关文章:

Levenberg–Marquardt 算法的 C# 实现

c - 协助使用C代码和汇编代码绘制堆栈

assembly - 气体 : jmp to label results in wrong jump?

c - 汇编中的静态和非静态变量

c - 寻找 asm 的等效 c 代码

assembly - 为什么 MIPS 汇编器将 subi 转换为 2 条指令?

c# - 做这个。减慢代码?

c# - 在 Xamarin.Forms 上加载图像时内存不足

c# - 如何在 ASP.NET Web API 中使用缓存?

c# - 组合 Datepicker 和 Timepicker 值 Win 8.1