想在软件中用点内嵌汇编,提升一下软件的档次 ( 积分: 50 )

  • 主题发起人 主题发起人 我爱PASCAL
  • 开始时间 开始时间

我爱PASCAL

Unregistered / Unconfirmed
GUEST, unregistred user!
在软件中我已经用上指针了,档次已有显著提高
想内嵌两句汇编,进一步提升档次
比如
tmp := a;
a := b;
b := tmp;
的tmp我不想用变量。我想用寄存器。
 
那自己看看汇编书啊。这个不难。
 
这也叫提高啊....

变量本身就是使用寄存器或者堆栈,你tmp不使用是完全没意思的.会干扰编译器工作.
 
var
i: integer;
begin
i := 0;
asm
mov eax, 100
inc eax
mov i, eax
end;
{i现在等于101了}
end;
有关basm的入门教程网上很多的。
 
还有,如果楼主只是想故弄玄虚的话,可以先用pascal代码写好,然后运行,然后在cpu窗口内把汇编拷出来,整理一下后写回程序内。
这样,代码就难阅读多了。[:D]
 
var
a,b:word;
begin
a:=1;
b:=5;
asm
push ax
push bx
mov ax,word ptr a
mov bx,word ptr b
mov word ptr b,ax
mov word ptr a,bx
pop bx
pop ax
end;
end;
 
几行汇编,能提高什么档次?做视频解码,图像压缩那才见效果。
 
tmp := a;
a := b;
b := tmp;

----------
asm
mov eax, a
mov ebx, b
push eax
push ebx
pop eax
pop ebx
mov a, eax
mov b, ebx
end;
 
会使用汇编,再使用高级语言就懂得许多优化算法!
 
来自:ufo!, 时间:2007-5-30 20:08:39, ID:3731377
还有,如果楼主只是想故弄玄虚的话,可以先用pascal代码写好,然后运行,然后在cpu窗口内把汇编拷出来,整理一下后写回程序内。
这样,代码就难阅读多了。[:D]

呵呵,好办法,这样看上去软件的档次一定高了不少:)
 
asm
mov eax, a
mov ebx, b
push eax
push ebx
pop eax
pop ebx
mov a, eax
mov b, ebx
end

这段好像不精简吧:
asm
mov eax, a
mov ebx, b
mov a, ebx
mov b, eax
end

这样不行吗
 
asm
XCHG EAX, A
XCHG EAX, B
XCHG EAX, A
end;
 
asm
XCHG EAX, A
XCHG EAX, B
XCHG EAX, A
end;
是不是执行更快
 
asm
push a
push b
pop a
pop b
end;
 
XCHG EAX, A
XCHG EAX, B
XCHG EAX, A

tmp := a;
a := b;
b := tmp;
还要慢很多
 
我就怀疑XCHG比较慢
是不是汇编里的一种宏?我不想用宏,我想用尽可能少的机器码(不是汇编的语句)
速度还要快。因为我这些简单的几句,每次执行都会重复几百万到上亿次。
因为我觉得:
tmp := a;
a := b;
b := tmp;
是用一个变量来交换的,可能比寄存器慢。但是大家给的代码都要压栈出栈。为什么要这样
变量都得这样吗。我的汇编知识很差,因为没学过。听人讲过一些,有一点概念。
 
xchg 肯定要慢,但要说明的是,它不是宏,慢是因为他要锁总线,我提供的代码
只是长度小,如果我没记错应该是9字节,速度没考虑

其实最快应该是,我猜测, a->eax, b->ecx, ecx->a, eax->b,因为这样
可以并发执行,不过代码就要12字节了,呵呵

对于如何优化才能最快,记得有篇优化指南,你可以找找,大约是这个名字
《IA-32 Intel Architecture Optimization Reference Manual》
 
晕!Delphi随着版本升级,其源码中的汇编越来越少,楼主是要反其道而行之了.
 
假设按约定参数a在eax,参数b在edx
那么这样应该是最快的:
mov ecx eax
mov eax edx
mov edx ecx
另外,如果a加 b不会溢出的话,还可以这么做:
a:= a+ b;
b:= a- b;
a:= a- b;
 
测试结果来了

按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
 
后退
顶部