测试结果来了
按delphi编译的结果,procedure test1(var a, b: Integer)确定了a 放在内存的地址
[eax],b 放在内存的地址[edx]
另外 ebx 是 delphi 用于循环计数的寄存器,要使用必须先保护,前面的 ID:3731804
提到的方法,没有保护 ebx 是问题的。
如下实时线程下,每次测试进行100万次循环调用下面过程,得出结果,并重复多次测试,
各次测试结果仅相差1ms。
procedure test1(var a, b: Integer)
// 3340ms
begin
asm
XCHG EAX, A
XCHG EAX, B
XCHG EAX, A
end;
end;
procedure test2(var a, b: Integer)
// 3340ms
begin
asm
MOV ECX, [EDX]
XCHG [EAX], ECX
MOV [EDX], ECX
end;
end
//执行XCHG要Lock总线,这里说明,无论是单次或者连续执行XCHG都只Lock一次,
//同时也说明Lock总线要花很长时间
procedure test3(var a, b: Integer)
// 2079ms
begin
asm
push a
push b
pop a
pop b
end;
end
//将地址即时地址进行栈操作要花时间
procedure test4(var a, b: Integer)
// 1896ms
begin
a := a + b;
b := a - b;
a := a - b;
end
//运算也花时间,这个程序有会溢出风险
procedure test5(var a, b: Integer)
// 1748ms
begin
a := a xor b;
b := a xor b;
a := a xor b;
end
//运算也花时间,程序比test4安全
procedure test6(var a, b: Integer)
// 1431ms
begin
asm
push [EAX]
push [EDX]
pop [EAX]
pop [EDX]
end;
end
//通过地址指针进行栈操作
procedure test7(var a, b: Integer)
// 1049ms 等效于test8
var
tmp: Integer;
begin
tmp := a;
a := b;
b := tmp;
end
//完全delphi版
procedure test8(var a, b: Integer)
// 1049ms 等效于test7
begin
asm
push EBX
mov ECX, [EAX]
mov EBX, [EDX]
mov [EAX], EBX
mov [EDX], ECX
pop EBX
end;
end
//等效于delphi版的代码,这里不能说delphi的编译效率已经非常好,也不能说汇编
//语言效率低,只是在delphi的嵌入asm的有诸多限制,在这种环境下,有时候真的
//无法写出比完全delphi版编译之后更快的asm代码。
所有给楼主的答案是test8