随便写了一个数组有关的代码:
int[] HistGram = new int[256];
HistGram[2]++;
然后设置一个断点,运行后,在断点哪一行点右键,反汇编,得到 HistGram[2]++这一行的汇编码 :
HistGram[2]++;
00000037 mov eax,dword ptr [ebp-0Ch]
0000003a cmp dword ptr [eax+4],2
0000003e ja 00000045
00000040 call 65247754
00000045 lea eax,[eax+10h]
00000048 mov dword ptr [ebp-14h],eax
0000004b mov eax,dword ptr [ebp-14h]
0000004e inc dword ptr [eax]
我先按照我的理解来解释下上面的几行代码:
mov eax,dword ptr [ebp-0Ch]
cmp dword ptr [eax+4],2 这两句应该是用来比较当前要使用的数组的索引是否大于数组的上标
ja 00000045 如果不大于,则跳转到00000045 行代码,否则call 65247754 应该是个异常抛出。
lea eax,[eax+10h] 设置eax寄存器的内容为HistGram[2]在内存中的地址
然后最后一句 inc dword ptr [eax] 就是将该地址中的内容++了。
因此,我就有2个问题了:
1: mov dword ptr [ebp-14h],eax
mov eax,dword ptr [ebp-14h]
这两句有什么用,如果说第一句有用,那也根本不需要第二句啊,有了第一句,那个内存中的内容和EAX的内容也就完全相同了嘛,还有,这两句似乎和我要执行的操作毫无关系啊。
2、如果我能完全确认我的代码访问数组的时候不会存在上下标越界的情况,在C#中有没有设置的选项让对应的汇编语言不产生这样的判断语句呢?因为我最关心的就是效率。
------解决方案--------------------------------------------------------
C#下标越界?你写一个出来给我看看。
下标越界检测和性能也没有一毛钱的关系。
计算机原理不清楚,搞来搞去,以为听说几个名词,其实一点用也没有。
------解决方案--------------------------------------------------------
1。
clrR的运算都是在evaluation stack上完成的,JIT生成本机代码可能没有那么智能,所以还是保留了保存和读取栈变量的指令,虽然这两句确实应该是没用的。
这段代码的IL是这样的:
.entrypoint
// Code size 33 (0x21)
.maxstack 3
.locals init ([0] int32[] HistGram)
IL_0000: nop
IL_0001: ldc.i4 0x100
IL_0006: newarr [mscorlib]System.Int32
IL_000b: stloc.0
IL_000c: ldloc.0
IL_000d: ldc.i4.2
IL_000e: ldelema [mscorlib]System.Int32
IL_0013: dup
IL_0014: ldobj [mscorlib]System.Int32
IL_0019: ldc.i4.1
IL_001a: add
IL_001b: stobj [mscorlib]System.Int32
IL_0020: ret