百科问答小站 logo
百科问答小站 font logo



有什么像a=a+b;b=a-b;a=a-b;这样的算法或者知识? 第1页

  

user avatar   wang-xuan-12-89 网友的相关建议: 
      

既然这种“算法”好,不看汇编肯定是没有说服力的。以下是多种C语言交换变量的汇编:

一、传统的临时变量法

tmp = a;

a = b;

b = tmp;

把上述代码编译:

mov eax,dword ptr [a]

mov dword ptr [tmp],eax

mov eax,dword ptr [b]

mov dword ptr [a],eax

mov eax,dword ptr [tmp]

mov dword ptr [b],eax

6个mov指令,很直观,用eax寄存器做倒手,完成三次变量赋值操作,每次赋值是2个mov指令。效果中规中矩,何乐而不为?

二、加减法:

a = a+b;

b = a-b;

a = a-b;

汇编:

mov eax,dword ptr [a]

add eax,dword ptr [b]

mov dword ptr [a],eax

mov eax,dword ptr [a]

sub eax,dword ptr [b]

mov dword ptr [b],eax

mov eax,dword ptr [a]

sub eax,dword ptr [b]

mov dword ptr [a],eax

6个mov+1个add+2个sub,一共9个指令!你可能会说,为什么会这样?C语言里同样是3个语句,为啥临时变量法和加减法会产生不同的汇编指令数量?这是因为加减法需要先将操作数复制到寄存器(eax)里,再做加减法运算。事实证明这样做除了节省一个整数的空间外,在效率和可读性上远比临时变量法差。平常千万不要用。

三、异或法:

a = a^b;

b = a^b;

a = a^b;

汇编:

mov eax,dword ptr [a]

xor eax,dword ptr [b]

mov dword ptr [a],eax

mov eax,dword ptr [a]

xor eax,dword ptr [b]

mov dword ptr [b],eax

mov eax,dword ptr [a]

xor eax,dword ptr [b]

mov dword ptr [a],eax

同样是9个汇编指令,和加减法一样,需要把变量移入eax再做计算。考虑到异或运算快于加减运算,所以只比加减法好一丁点。这方法也非常糟糕,平常千万不要用。

四、内联汇编版

有没有既不需要内存变量又高效的方法呢,有!那就是内联汇编

__asm{

mov eax,a

xchg eax,b

mov a,eax

}

将内联汇编代码插入__asm{}块内,简简单单三句指令,第一句将a复制入寄存器eax内,第二句将eax和b交换,第三句将eax复制入a内。这样做的优点就是充分发挥了汇编的高效,不需要额外内存变量做临时变量。缺点是代码可读性差,不懂汇编的读着会懵逼。所以,该不该这样用,还得看实际情况

——————————

根据评论区给出的建议,已将原来的“反汇编”改为“汇编”和“编译”

虽然我的汇编代码是用VS的反汇编查看的,但这里用“编译”才是这种优化方法的思想本质。




  

相关话题

  一行代码可以做什么? 
  以前 CSDN 很好,但是现在只有提问的,都是没人回复,没人参与了,现在的程序员遇到问题用什么交流呢? 
  实际工作中的 C++ 项目都是没有内存泄漏的么? 
  C#里面将对象实例赋值为null会否加速GC释放资源? 
  Windows自带的文本编辑器原理? 
  windows10 界面是用什么语言编写的?.NET在最新的操作系统中有哪些应用 
  为什么指针不能相加? 
  C++ 有哪些缺点? 
  为什么程序比较难写、bug 比较难调呢? 
  如何评价《轩辕剑外传穹之扉》制作人杨渊升针称《巫师 3》「200 人三年的制作规模,我们真的也可以」? 

前一个讨论
为什么物理学家在决定论和量子力学中选择了后者?
下一个讨论
不同价位的瓶装水有什么区别?





© 2025-04-15 - tinynew.org. All Rights Reserved.
© 2025-04-15 - tinynew.org. 保留所有权利