不借助第三个临时数交换两个整数,无外乎进行所谓的数字魔术,或借助寄存器实现,但除此外还有一种“巧妙的”方法:通过 XOR 变换实现——不过论其本质,还是所谓的数字魔术,:-) ...
        随手测试了下 数字魔术、借助寄存器(纯 Asm 实现) 及 XOR变换 的效率,耗时显示,纯 Asm 实现 < XOR变换 < 数字魔术——结果当然不出意料,纯Asm实现 比另两者快很多。
 
Delphi 测试代码:
program Project1;
{$APPTYPE CONSOLE}
uses
  SysUtils, Windows;
var
  I, J, K, M, N: Integer;
begin
  // the BASE arithmetic ...
  M := 1;
  N := 2;
  K := GetTickCount;
  for I := 0 to 5000 do
  begin
    for J := 0 to 5000 do
    begin
      M := M + N;
      N := M - N;
      M := M - N;
    end;
  end;
  K := GetTickCount - K;
  Writeln(K, ';', M, ';', N);
  ReadLn;
  // use Registers ...
  M := 1;
  N := 2;
  K := GetTickCount;
  asm         // EAX: 循环计数; ECX: I; EDX: J; EBX: M; EDI: N
              PUSH    EBX
              PUSH    EDI
              MOV     EBX, M
              MOV     EDI, N
              MOV     EAX, 5000
              MOV     ECX, 0
  @Loop1:     CMP     ECX, EAX
              JA      @Loop1End
              MOV     EDX, 0
  @Loop2:     CMP     EDX, EAX
              JA      @Loop2End
              XCHG    EBX, EDI
              INC     EDX
              JMP     @Loop2
  @Loop2End:  INC     ECX
              JMP     @Loop1
  @Loop1End:  MOV     M, EBX
              MOV     N, EDI
              POP     EDI
              POP     EBX
  end;  
  K := GetTickCount - K;
  Writeln(K, ';', M, ';', N);
  ReadLn;
  // Now XOR ...
  M := 1;
  N := 2;
  K := GetTickCount;
  for I := 0 to 5000 do
  begin
    for J := 0 to 5000 do
    begin
      M := M xor N;
      N := N xor M;
      M := M xor N;
    end;
  end;
  K := GetTickCount - K;
  Writeln(K, ';', M, ';', N);
  ReadLn;
end.
 
P.S:以 VC 6.0 + SP6 测试了同样效果的代码,Release 下其结果明显快于 Delphi 的数字魔术(但仍比 纯Asm实现 慢一些) ...Delphi 优化器确实较差,没办法。
VC 测试代码:
#include <iostream>
#include <windows.h>
void main()
{
 int I, J, K, M, N;
 
 M = 1;
 N = 2;
    K = GetTickCount();
 for (I = 0; I <= 5000; I++)
    {
  for (J = 0; J <= 5000; J++)
  {
    M = M + N;
    N = M - N;
    M = M - N;
  }
 }
 K = GetTickCount() - K;
 printf("%d;%d;%d\n", K, M, N);
}
图片
图片