免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: guoruimin
打印 上一主题 下一主题

[C] 使用C语言,要不要了解汇编? [复制链接]

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
111 [报告]
发表于 2011-11-11 21:27 |只看该作者
本帖最后由 yulihua49 于 2011-11-11 22:37 编辑
回复  yulihua49

你还没回复我们O(log2(n))的二叉树排序算法是怎么回事呢。

OwnWaterloo 发表于 2011-11-11 19:40



    这不是不谨慎,而是我认为尽人皆知。
我说的是平衡二叉树吧?如果当时漏了现在补上平衡二字。如果还不能理解,我再证明。
红黑树可能更好一些建议你试试再说。

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
112 [报告]
发表于 2011-11-11 21:34 |只看该作者
本帖最后由 yulihua49 于 2011-11-11 21:43 编辑
回复  yulihua49

自己看看楼下的回复里, 是不是eax*edx, 是不是 (i)mul。  好多指令是哪来的, 慢十几倍从何说起?
后续回复更是夸张到"不慢几十倍有鬼"。
OwnWaterloo 发表于 2011-11-11 19:40


imul的问题我前边解释了。
你还是没看明白,编译的结果,32积,而不是64位。弄个64位积你看看。
我告你一个办法,慢不了几十倍,慢几倍是有的。如果是64*64=128的,几十倍不夸张。

就是10页99楼的那个,用long long过渡一下,你把那个程序反汇编一下看看多少指令。

你有空写一个64bit×64bit=128bit,128bit/64bit=64bit余64bit的算法,我下周如果有空做个测试。
怕你说我的算法不优,用你的验证一下。

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
113 [报告]
发表于 2011-11-11 21:51 |只看该作者
本帖最后由 yulihua49 于 2011-11-11 22:30 编辑
回复  yulihua49

自己看看楼下的回复里, 是不是eax*edx, 是不是 (i)mul。  好多指令是哪来的, 慢十几倍从何说起?
OwnWaterloo 发表于 2011-11-11 19:40



    85楼的程序,cdq指令(将eax扩展到edx),完了。能不用这条指令吗?edx是要的啊。还要赋值出来。
在有限域运算中乘法在溢出状态是常态,而除法必须是规格化的,就是除数最高位永远是1。如采用普通的除法的商永远是0,必须双字除法。
如果除数最高位不是1,那就要做规格化,被除数和除数都左移直到除数最高位为1。这一套操作,C好累啊,asm很简单的,一系列的带进位移位而已。
要实现完全的双字乘法你至少要做3次乘法(不优化需4次)才能补齐那丢失的edx。
99楼的32汇编就用3个乘法出64位结果的。
如果64位机,一个乘法可以,但丢掉了rdx。

如果是除法,128/64的,就是用长除,试商,乘减,不对修商,再来,余数延长再一圈,含有多少乘除指令?汇编就一条,差不只十几倍。

论坛徽章:
0
114 [报告]
发表于 2011-11-12 19:28 |只看该作者
本帖最后由 AD8018 于 2011-11-12 19:40 编辑
哪个编译器给你双字除法了?
在64位编译器上,只提供了64bit/64bit商64bit,哪有128bit的?你告 ...
yulihua49 发表于 2011-11-11 13:01



    64位的我不清楚。

我在32位的机器上,可以用64位的除法,

   long long a, b, c;
   ...
   a = b / c;

这个可以证明编译器的确有双字的除法 。

论坛徽章:
0
115 [报告]
发表于 2011-11-12 19:36 |只看该作者
带进位循环移位,加减法的进位和溢出判断,汇编就是一条指令,C就玩大了。
测试并复位,测试并置位,原子操作。C呢?得mutex_lock了吧?
yulihua49 发表于 2011-11-11 13:06


测试并复位,
windows下有一系列 Interlocked** 函数呢。。

论坛徽章:
0
116 [报告]
发表于 2011-11-12 19:39 |只看该作者
我觉得这个论题很搞笑,
C有C的用途,汇编有汇编的用途,
用A的长处,无法证明用B的人要不要用A。

正如我主打写C的,做项目时,实际经常5,6种语言都要用到。。

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
117 [报告]
发表于 2011-11-12 19:47 |只看该作者
本帖最后由 yulihua49 于 2011-11-12 20:07 编辑
我觉得这个论题很搞笑,
C有C的用途,汇编有汇编的用途,
用A的长处,无法证明用B的人要不要用A。

正如 ...
AD8018 发表于 2011-11-12 19:39



    只不过是说,有时汇编会有用,会一点汇编没坏处。
双字乘除法不是那个意思。
你以64bit对象做的也是单字乘除法。真正机器指令的双字乘除法,指:
两个机器字相乘会出现双倍长度的数字,比方:在32bit上,
unsigned int a=0X80000000;b=0X80000000,c=a*b?
c就应该是一个64bit的数字。
你举的例子,应该解这个问题:
unsigned long long a=0X8000000000000000;
unsigned long long b=0X8000000000000000;
unsigned long long long c=a*b;//没这个类型吧?,那么
unsigned long long c[2];
unsigned long long q,r;

                       q=diva64(c,b,&r); //结果:q=b,r=0;
      mula64(a,b,c);//就是这个,用什么算法效率较高?

不管你的数字多长,乘积和被除数一定是双倍长。这是组装大数运算的必要条件。
现在的大数运算,可以基于bit、BYTE、short、int32_t。但不能int64_t。
如果必须,可以asm。

论坛徽章:
0
118 [报告]
发表于 2011-11-12 20:06 |只看该作者
本帖最后由 AD8018 于 2011-11-12 20:08 编辑
只不过是说,有时汇编会有用,会一点汇编没坏处。
双字乘除法不是那个意思。
你以64bit对象做的 ...
yulihua49 发表于 2011-11-12 19:47



    简单测试了一下,32位机器下的结果:

  1. unsigned long long mul(unsigned long a, unsigned long b)
  2. {
  3.      return a * (unsigned long long)b;
  4. }
复制代码
编译结果这样,显示出两个32位一步生成64位,这个算“双字” 的乘法吗?


  1. .globl _mul
  2.     .def    _mul;   .scl    2;  .type   32; .endef
  3. _mul:
  4.     pushl   %ebp
  5.     movl    %esp, %ebp
  6.     movl    12(%ebp), %eax
  7.     mull    8(%ebp)
  8.     popl    %ebp
  9.     ret
复制代码

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
119 [报告]
发表于 2011-11-12 20:12 |只看该作者
本帖最后由 yulihua49 于 2011-11-12 20:13 编辑
简单测试了一下,32位机器下的结果:编译结果这样,显示出两个32位一步生成64位,这个算“双字” ...
AD8018 发表于 2011-11-12 20:06


这个是。我回头看一下。现在的编译器聪明了。以前的编译器不肯这么干。
64位的可能还有问题,因为没有long long long类型。

论坛徽章:
0
120 [报告]
发表于 2011-11-12 20:13 |只看该作者
这个是。我回头看一下。现在的编译器聪明了。以前的编译器不肯这么干。
yulihua49 发表于 2011-11-12 20:12



    刚才加 -O2 它才这么干的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP