反汇编C#的一些很简单的代码,有些疑问,请大家帮忙释疑。

laviewpbt 2012-12-16 09:40:48
随便写了一个数组有关的代码:


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#中有没有设置的选项让对应的汇编语言不产生这样的判断语句呢?因为我最关心的就是效率。
...全文
1034 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
Delta 2012-12-19
  • 打赏
  • 举报
回复
来看看。有点意思,呵呵。
ghao0 2012-12-19
  • 打赏
  • 举报
回复
引用 21 楼 caozhy 的回复:
引用 20 楼 laviewpbt 的回复: caozhy,不管你的出发点如何,你的大部分发言在我看来都有份盛气凌人的霸气。不是每个人都喜欢这种语气的。 你不让我在C#发言或发帖我其实无所谓。我研究的东西本来用C#在搞的也不多。 我有很多帖子无满意结贴是因为他们不少都是我用来共享代码或资源,并不是我向大家索求答案,别人得到了资源比得到那个无用的分数更实在。我懒得在那个分配分数上浪费时……
版主是个聪明人,节省说好话的时间来研究技术。在技术堆中和长期接触中会成长,不过遇到不懂行的或不太懂得就有问题,毕竟大家都喜欢听好话,不会说好话可能难以作管理呀。 一人之谈,一面之谈,难免不周。
七神之光 2012-12-18
  • 打赏
  • 举报
回复
skyshout 2012-12-18
  • 打赏
  • 举报
回复
做技术的,谦虚点好!
skyshout 2012-12-18
  • 打赏
  • 举报
回复
引用 21 楼 caozhy 的回复:
引用 20 楼 laviewpbt 的回复:caozhy,不管你的出发点如何,你的大部分发言在我看来都有份盛气凌人的霸气。不是每个人都喜欢这种语气的。 你不让我在C#发言或发帖我其实无所谓。我研究的东西本来用C#在搞的也不多。 我有很多帖子无满意结贴是因为他们不少都是我用来共享代码或资源,并不是我向大家索求答案,别人得到了资源比得到那个无用的分数更实在。我懒得……
caozhy版主说和不错啊,做技术的,谦虚点好,要知道山外有山,人外有人啊。 顺便介绍一下程序员之家,也是一个不错的IT技术网站。
threenewbee 2012-12-17
  • 打赏
  • 举报
回复
引用 5 楼 jshi123 的回复:
1。 clrR的运算都是在evaluation stack上完成的,JIT生成本机代码可能没有那么智能,所以还是保留了保存和读取栈变量的指令,虽然这两句确实应该是没用的。 这段代码的IL是这样的: Plain Text code?1234567891011121314151617 .entrypoint // Code size 33 (0x21) ……
事实上CLR不是弱智,那只是调试版本的输出。 我特地跑了一下,在release版本(再次强调,这些代码只和我本机环境,当前CLR有关,因为这是JIT编译器产生的)机器代码是这样的: ... 002A0048 int 3 002A0049 push ss 002A004A and eax,dword ptr [eax] 002A004C xchg eax,esp 002A004D aaa 002A004E and eax,dword ptr [eax] 002A0050 push ebp 002A0051 mov ebp,esp 002A0053 mov ecx,68A04C8Ah 002A0058 mov edx,100h 002A005D call 00222214 002A0062 mov edx,eax 002A0064 cmp dword ptr [edx+4],2 002A0068 jbe 002A008B 002A006A lea eax,[edx+10h] 002A006D inc dword ptr [eax] 你可以看到那两条Mov指令都没有了。
laviewpbt 2012-12-17
  • 打赏
  • 举报
回复
了解了,谢谢各位。 虽然 我的账户 被 您的帐户被限制发帖,如有疑问请联系版主或论坛管理员
threenewbee 2012-12-17
  • 打赏
  • 举报
回复
引用 20 楼 laviewpbt 的回复:
caozhy,不管你的出发点如何,你的大部分发言在我看来都有份盛气凌人的霸气。不是每个人都喜欢这种语气的。 你不让我在C#发言或发帖我其实无所谓。我研究的东西本来用C#在搞的也不多。 我有很多帖子无满意结贴是因为他们不少都是我用来共享代码或资源,并不是我向大家索求答案,别人得到了资源比得到那个无用的分数更实在。我懒得在那个分配分数上浪费时间。
非技术贴可以平均分配分数。我给你解封了,我只想说一点,你有你的无满意结帖的理由,我尊重你的理由,但是希望你以后也尊重C#版的规则,如果没有规则,就会在处理各种问题的时候难免厚此薄彼。 我不期待每一个人都喜欢我的语气,每个人都很忙,做到自己问心无愧就可以了。退一万步说,即便你认为我很讨厌你,我在故意贬低你的技术水准,你也没有必要在意,因为我再怎么贬低你,你的技术水平也不会低一分。当然反过来说,我恭维你,你的技术水平也不会涨一分。也许我很不在意别人的褒贬,所以我有时候也容易忽略这一点。我说了,我热爱技术,我可以为了技术放弃自尊心,为了技术可以忽略一些现实的利益,这是我的价值观,我同样很欣赏和我一样技术至上的人,无论他们水平在我之上还是在我之下,我认为我的好朋友圈子都是这样的人。 我不要求每一个人的价值观和我一样,我知道很多人探究技术,但是有其他的追求,比如仅仅是对工作的负责,或者是在学业中取得成绩,他们把技术当作工具,而不是追求,我理解他们,但是,我没有更多的精力讨这些人的欢心,在我看来,这样的人,无论技术高低,终究对我来说(同时我对他来说),都只是人海中匆匆相遇又匆匆分别的路人,而只有热爱技术本身的人,无论他技术高低,只是在这条路上先走后者晚走几步,却可以陪我一直走下去。
laviewpbt 2012-12-17
  • 打赏
  • 举报
回复
caozhy,不管你的出发点如何,你的大部分发言在我看来都有份盛气凌人的霸气。不是每个人都喜欢这种语气的。 你不让我在C#发言或发帖我其实无所谓。我研究的东西本来用C#在搞的也不多。 我有很多帖子无满意结贴是因为他们不少都是我用来共享代码或资源,并不是我向大家索求答案,别人得到了资源比得到那个无用的分数更实在。我懒得在那个分配分数上浪费时间。
threenewbee 2012-12-17
  • 打赏
  • 举报
回复
不会才来问问题,问问题就把问题说说清楚,尤其是问题的背景。每个人都应该好好看看《提问的智慧》,尤其是我们板的野比前两天还特地发了他评论的精读版本。 我看到我能帮上忙的,就帮一把,在论坛的一个好处是,你还可以帮助到别的人。看到问题都没有问对的,就给纠正下。对的就是对的,错的就是错的。意见有分歧可以讨论,有什么好顾忌的。问问题不关注问题本身,关注的是回答问问题的人技术不如我,就伤害了我的自尊心,那还怎么进步。你看看C#版的大牛,sp1234、bdmh斑竹、子夜,包括这个贴的jshi123,哪个人说的我觉得有什么不同观点,我就说两句,又怎么了呢? 再说我说的也并非真理,无论是大牛,还是只有一个三角我都不知道是谁的网友,指出我的错误,我意识到确实错了的,我就说我错了。(随便用我的id在google搜,第二页就能搜到一个,http://bbs.csdn.net/topics/390065843)我为什么要在论坛公开认错,这无关乎面子问题,我觉得这可以更好地帮助论坛的后来者,不要因为他们看到论坛观点有不同,而轻易相信那个好几个星的而忽略了那个三角的,这就让我于心不安了。 我不是高手,我在csdn的等级挺高只是因为我比较热心,也因为技术不但是我的职业,也是我的热爱,所以不计报酬地讨论技术我很快乐。虽然我不是高手,但是我可以看到我的进步,至少每年我都比去年的我强。有的人也说他热爱技术,热爱编程,我不知道他怎么个热爱法。但是我能做到,为了技术放弃自尊心,为了技术可以忽略一些现实的利益,就是如此。
threenewbee 2012-12-17
  • 打赏
  • 举报
回复
引用 17 楼 lddp034 的回复:
大家都在讨论问题,却因为一个问题封ID不让发帖。。【版主】不淡定了。。
你以为我封他是报私仇?你看看他的历史发帖记录,有多少无满意答案结帖?有的贴回了几百楼,都给他说不满意就不满意结了。恶意无满意答案结帖是绝大多数csdn用户深恶痛绝的,在C#板,只要看到了,我就要管。我不管他是多么资深的高手,还是有几个花几个牌子。
lddp034 2012-12-17
  • 打赏
  • 举报
回复
大家都在讨论问题,却因为一个问题封ID不让发帖。。【版主】不淡定了。。
  • 打赏
  • 举报
回复
即便分支预测成功率100%(到目前为止还没有这样的处理器) 002A0064 cmp dword ptr [edx+4],2 002A0068 jbe 002A008B 这两条指令(教新的处理器上可以宏融合成一条指令)还是要执行的,还是需要时间,如果每个数组元素访问都增加这么一两条指令,怎么可能不影响性能呢。
laviewpbt 2012-12-17
  • 打赏
  • 举报
回复
引用 13 楼 sbwwkmyd 的回复:
使用unsafe指针就没有问题。 对于越界判断,简单的情况是可以被编译器优化掉的。否则编译器优化是靠不住的,运行效率差个几倍是正常的。
嗯,我用fixed获得HistGram的首地址,然后用指针访问后就没有那个检测了。
showjim 2012-12-17
  • 打赏
  • 举报
回复
引用 9 楼 caozhy 的回复:
特别注意 002A0064 cmp dword ptr [edx+4],2 002A0068 jbe 002A008B 显然,JIT为此生成了边界检查的代码,事实上除非你使用不安全代码,是无法阻止JIT这么做的。 进一步说,这个判断是否会降低“效率”呢,你试试就知道了,根本不会。现代处理器完全可以很聪明地正确预测这样的分支,所谓画蛇添足的“优化”毫无意义。
不知道你使用的什么处理器?分支预测效果这么好? 至少我使用过的处理器没有一个效果理想的。
showjim 2012-12-17
  • 打赏
  • 举报
回复
使用unsafe指针就没有问题。 对于越界判断,简单的情况是可以被编译器优化掉的。否则编译器优化是靠不住的,运行效率差个几倍是正常的。
threenewbee 2012-12-17
  • 打赏
  • 举报
回复
引用 6 楼 tomsoft 的回复:
引用 1 楼 caozhy 的回复:C#根本就不能产生你说的这些本机代码。C#只能产生IL,这些本机代码是JIT产生的。 又见大牛,这里似乎不是C#版块。C++/C会产生目标代码吗?老子不懂C#,作软件做了20年了
隔行如隔山,坦率地说,我不懂C/C++,就好比你搞了20年,也照样不懂C#一样。 虽然所有编程语言都是图灵等价的,C#并不能创造出比C++更多的功能,但是C#和C++除了语法上都是C Like以外,没有太多相似之处,抽象程度的高低决定了编程思维,用C的思维来写C#程序,如同给英语单词增加“汉语注解的拼音”一样,用这种方式你可以说英语,但是老外一听就知道你的发音和语法是不地道的。
jshi123 2012-12-17
  • 打赏
  • 举报
回复
嗯嗯,我看的是debug版本。 边界检查的话我也看错了,unchecked是溢出检查,数组边界检查应该是不能完全去掉了。 可以看这篇文章: http://blogs.msdn.com/b/clrcodegeneration/archive/2009/08/13/array-bounds-check-elimination-in-the-clr.aspx
threenewbee 2012-12-17
  • 打赏
  • 举报
回复
特别注意 002A0064 cmp dword ptr [edx+4],2 002A0068 jbe 002A008B 显然,JIT为此生成了边界检查的代码,事实上除非你使用不安全代码,是无法阻止JIT这么做的。 进一步说,这个判断是否会降低“效率”呢,你试试就知道了,根本不会。现代处理器完全可以很聪明地正确预测这样的分支,所谓画蛇添足的“优化”毫无意义。
「已注销」 2012-12-16
  • 打赏
  • 举报
回复
回LZ,请使用Release版本,如果是GCC请使用O2优化开关
加载更多回复(6)

21,458

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧