匯編高手請幫忙寫一個過程,大恩不言謝,300分!!!zjan521請進(300分)

Z

zdyue

Unregistered / Unconfirmed
GUEST, unregistred user!
目的: 返回兩個字符串對應位置的相同字符的個數.
定義: function getSameCharCount(a,b:string):integer;
asm
//用匯編語言編寫
end;
執行: 比如: a='abcd' b='cbce' result=2
又如: a='21' b='12' result=0
又如: a='123' b='103' result=2

約定: a,b是長度相等的字符串
該過程在DELPHI中掉用
 
zjan521,你在前帖中給出的回答和該函數要實現的功能稍微有點不同,我又不會改,
請幫忙.

另外,請個路諸侯幫忙.急切中!!!
 
function getSameCharCount(a,b:string):integer;
asm
pushf
push esi
push edi

mov esi, eax ;//a
mov edi, edx ;//b

xor ecx, ecx ;//用于保存相同字符数,初始化为0

cld
@@0:
lodsb
or al, al ;//判断是否结束, 因为String兼容PChar,所以采用了偷懒的办法,
;//正常应该读取实际长度
jz @@2
cmp al, byte ptr [edi]
jnz @@1
inc ecx ;//相同字符
@@1:
inc edi
jmp @@0

@@2:
mov eax, ecx ;//返回值

pop edi
pop esi
popf
end;
 
tseug,我對你寫的函數測試了一下.能返回正確的結果.
但是效率還沒有用PASCAL寫的高.
function getSameCharCountPas(a,b:string):integer;
var len,i:integer;
begin
result:=0;
len:=length(a);
for i:=0 to len-1 do
begin
if a[i+1]=b[i+1] then
inc(result);
end;
end;
我的比較結果
a:='310232222222320430438'
b:='310232222222320430438'
執行10000000次
匯編需要時間1.641秒
PAS需要時間1.328秒

請問為甚麼?
註:用PAS寫的函數假設了a,b的長度相同,我的要求也是a,b的長度相同.

請教.
 
那你试试这个

function getSameCharCount(a,b:string):integer;
asm
PUSH EBX
PUSH ESI
PUSH EDI

MOV EBX, EAX
MOV ESI, EDX

XOR EDI, EDI
XOR EAX, EAX

MOV EDX, [EBX-4]

@@0:
TEST EDX, EDX
JLE @@3
@@1:
MOV CL, [EBX+EAX-$00]
CMP CL, [ESI+EAX-$00]
JNZ @@2
INC EDI
@@2:
INC EAX
DEC EDX
JNZ @@0

@@3:
MOV EAX, EDI
POP EDI
POP ESI
POP EBX
end;
 
气死我了,我怎么写也写不出比PAS代码更快的,看样子下班回家要看书了,研究一下
CPU的指令周期,DELPHI优化得很不错,绝对比绝大多数人写的汇编代码高效。。。
 
这个应该比PAS的快了吧....[8D]

function getSameCharCount(a,b:string):integer;
asm
PUSH EBX
PUSH ESI

MOV EBX, EAX
MOV ESI, EDX

XOR EAX, EAX ;//结果

TEST EBX, EBX ;//判断是否空指针
JZ @@2
MOV EDX, [EBX-4] ;//获取字符串长度
TEST EDX, EDX
JLE @@2

@@0: ;//从最后一个字符向前循环比较
MOV CL, [EBX+EDX-1]
CMP CL, [ESI+EDX-1]
JNZ @@1
INC EAX ;//对应位置字符相同
@@1:
DEC EDX
JNZ @@0

@@2:
POP ESI
POP EBX
end;
 
好,最後一個最快,相同的測試需要0.563秒,PAS需要時間1.203秒
 
开始的代码是顺手写的,根本就没考虑效率的问题,尤其是思路还在8086上,没考虑
到CPU的并行操作,后来的代码一个是减少了无效的指令码,另一个是考虑了奔腾处理
器的并行处理,呵呵。。。
 
哈哈,高,以前學的8086指令早忘了,你還能記得.高
 
汗……
写的什么我看不懂
 
看不懂,汇编,天,。。。
 
我想,PAS的慢在过程进入时的一些操作,而不是循环体内的汇编代码的效率的问题,即使有也是不大的,效率是由于begin end产生的汇编代码引起的,如果你只比较一次的且很大的字串我相信两者的效率是差不多的,你看一下DELPHI的汇编化码就可以理解了.

 
汇编高手啊,我以前的一位主管就用汇编做了仿WINDOWS!!!
 
tseug,你好,還有一個算法需要優化.在麻煩幫一下,大富翁中就是高手多:
function getSpecialPositionSubStr(const str,model:string):string;
取特定位子的字符組成字符串
參數說明
str:是一個固定長度的字符串,長度為21
model:表示是否要取得字符位置,長多也是21,
用0表示不取對應位置得字符,1表示取對應位置得字符
比如str='123456789' model='101010101' result:='13579'
 
奇怪,每行代码我都明白,但是,我实在不知道这个过程是干什么的,呵呵
MOV EBX, EAX?//怎么知道参数一定在这儿呢,我也是只背过几条指令而已
MOV ESI, EDX?
 
說明一下一定要使用匯編的目的:

又一段程序算法是經過優化的,程序執行時間還是長,老闆不滿意,我等就只有在代碼上
修改,通過tseug的匯編代碼,程序的運行時間縮短了20%,對程序來說是一個不小的改進.

註:該程序一天要運行上面代碼很多很多次.
 
[8D]匯編我都望了好多了,高手們寫的我都好多看不懂了
 
吃饱没事做用汇编?
 
用另一只眼写的字符串快速替换中的函数试一下看看怎么样。
tseug 说的cpu并行处理,汇编中的那里帮忙给解释一下,
我的汇编仍然是8086呢
 
顶部