改写StrCopy和StrLCopy函数。(100分)

  • 主题发起人 主题发起人 go2u
  • 开始时间 开始时间
G

go2u

Unregistered / Unconfirmed
GUEST, unregistred user!
function StrCopy(Dest: PChar; const Source: PChar): PChar;<br>asm<br> &nbsp; &nbsp; &nbsp; &nbsp;PUSH &nbsp; &nbsp;EDI<br> &nbsp; &nbsp; &nbsp; &nbsp;PUSH &nbsp; &nbsp;ESI<br> &nbsp; &nbsp; &nbsp; &nbsp;MOV &nbsp; &nbsp; ESI,EAX<br> &nbsp; &nbsp; &nbsp; &nbsp;MOV &nbsp; &nbsp; EDI,EDX<br> &nbsp; &nbsp; &nbsp; &nbsp;MOV &nbsp; &nbsp; ECX,0FFFFFFFFH<br> &nbsp; &nbsp; &nbsp; &nbsp;XOR &nbsp; &nbsp; AL,AL<br> &nbsp; &nbsp; &nbsp; &nbsp;REPNE &nbsp; SCASB<br> &nbsp; &nbsp; &nbsp; &nbsp;NOT &nbsp; &nbsp; ECX<br> &nbsp; &nbsp; &nbsp; &nbsp;MOV &nbsp; &nbsp; EDI,ESI<br> &nbsp; &nbsp; &nbsp; &nbsp;MOV &nbsp; &nbsp; ESI,EDX<br> &nbsp; &nbsp; &nbsp; &nbsp;MOV &nbsp; &nbsp; EDX,ECX<br> &nbsp; &nbsp; &nbsp; &nbsp;MOV &nbsp; &nbsp; EAX,EDI<br> &nbsp; &nbsp; &nbsp; &nbsp;SHR &nbsp; &nbsp; ECX,2<br> &nbsp; &nbsp; &nbsp; &nbsp;REP &nbsp; &nbsp; MOVSD<br> &nbsp; &nbsp; &nbsp; &nbsp;MOV &nbsp; &nbsp; ECX,EDX<br> &nbsp; &nbsp; &nbsp; &nbsp;AND &nbsp; &nbsp; ECX,3<br> &nbsp; &nbsp; &nbsp; &nbsp;REP &nbsp; &nbsp; MOVSB<br> &nbsp; &nbsp; &nbsp; &nbsp;POP &nbsp; &nbsp; ESI<br> &nbsp; &nbsp; &nbsp; &nbsp;POP &nbsp; &nbsp; EDI<br>end;<br><br>function StrLCopy(Dest: PChar; const Source: PChar; MaxLen: Cardinal): PChar; assembler;<br>asm<br> &nbsp; &nbsp; &nbsp; &nbsp;PUSH &nbsp; &nbsp;EDI<br> &nbsp; &nbsp; &nbsp; &nbsp;PUSH &nbsp; &nbsp;ESI<br> &nbsp; &nbsp; &nbsp; &nbsp;PUSH &nbsp; &nbsp;EBX<br> &nbsp; &nbsp; &nbsp; &nbsp;MOV &nbsp; &nbsp; ESI,EAX<br> &nbsp; &nbsp; &nbsp; &nbsp;MOV &nbsp; &nbsp; EDI,EDX<br> &nbsp; &nbsp; &nbsp; &nbsp;MOV &nbsp; &nbsp; EBX,ECX<br> &nbsp; &nbsp; &nbsp; &nbsp;XOR &nbsp; &nbsp; AL,AL<br> &nbsp; &nbsp; &nbsp; &nbsp;TEST &nbsp; &nbsp;ECX,ECX<br> &nbsp; &nbsp; &nbsp; &nbsp;JZ &nbsp; &nbsp; &nbsp;@@1<br> &nbsp; &nbsp; &nbsp; &nbsp;REPNE &nbsp; SCASB<br> &nbsp; &nbsp; &nbsp; &nbsp;JNE &nbsp; &nbsp; @@1<br> &nbsp; &nbsp; &nbsp; &nbsp;INC &nbsp; &nbsp; ECX<br>@@1: &nbsp; &nbsp;SUB &nbsp; &nbsp; EBX,ECX<br> &nbsp; &nbsp; &nbsp; &nbsp;MOV &nbsp; &nbsp; EDI,ESI<br> &nbsp; &nbsp; &nbsp; &nbsp;MOV &nbsp; &nbsp; ESI,EDX<br> &nbsp; &nbsp; &nbsp; &nbsp;MOV &nbsp; &nbsp; EDX,EDI<br> &nbsp; &nbsp; &nbsp; &nbsp;MOV &nbsp; &nbsp; ECX,EBX<br> &nbsp; &nbsp; &nbsp; &nbsp;SHR &nbsp; &nbsp; ECX,2<br> &nbsp; &nbsp; &nbsp; &nbsp;REP &nbsp; &nbsp; MOVSD<br> &nbsp; &nbsp; &nbsp; &nbsp;MOV &nbsp; &nbsp; ECX,EBX<br> &nbsp; &nbsp; &nbsp; &nbsp;AND &nbsp; &nbsp; ECX,3<br> &nbsp; &nbsp; &nbsp; &nbsp;REP &nbsp; &nbsp; MOVSB<br> &nbsp; &nbsp; &nbsp; &nbsp;STOSB<br> &nbsp; &nbsp; &nbsp; &nbsp;MOV &nbsp; &nbsp; EAX,EDX<br> &nbsp; &nbsp; &nbsp; &nbsp;POP &nbsp; &nbsp; EBX<br> &nbsp; &nbsp; &nbsp; &nbsp;POP &nbsp; &nbsp; ESI<br> &nbsp; &nbsp; &nbsp; &nbsp;POP &nbsp; &nbsp; EDI<br>end;<br><br>这两个函数,复制字符串时遇到NULL(#0)就停止复制了,请汇编高手改改。使复制遇到NULL也不停止复制,直到复制完成StrCopy ,或者到指定长度才停止复制StrLCopy。
 
问错地方了?哪里问汇编的?
 
直接用CopyMemory不得了?
 
procedure StrCopy(Src: PChar; SrcLen: Integer; Dest: PChar; DestLen: Integer; AFillChar: Char = #0); overload;<br>var<br> &nbsp;L: Integer;<br>begin<br> &nbsp;FillChar(Dest^, DestLen, AFillChar);<br> &nbsp;<br> &nbsp;if SrcLen &gt; DestLen then <br> &nbsp; &nbsp;L := DestLen<br> &nbsp;else<br> &nbsp; &nbsp;L := SrcLen;<br><br> &nbsp;if L &gt; 0 then &nbsp;<br> &nbsp; &nbsp;Move(Src^, Dest^, L);<br>end;<br><br>procedure StrCopy(const Source: string; Dest: PChar; MaxLen: Integer; AFillChar: Char = #0); overload;<br>begin<br> &nbsp;StrCopy(PChar(Source), Length(Source), Dest, MaxLen);<br>end;
 
是一个要求速度的地方,希望能用到汇编.
 
直接用CopyMemory不得了? <br>procedure CopyMemory(Destination: Pointer; Source: Pointer; Length: DWORD);<br>begin<br> &nbsp;Move(Source^, Destination^, Length);<br>end;<br>procedure &nbsp; &nbsp; &nbsp; Move( const Source; var Dest; count : Integer );<br>{$IFDEF PUREPASCAL}<br>var<br> &nbsp;S, D: PChar;<br> &nbsp;I: Integer;<br>begin<br> &nbsp;S := PChar(@Source);<br> &nbsp;D := PChar(@Dest);<br> &nbsp;if S = D then Exit;<br> &nbsp;if Cardinal(D) &gt; Cardinal(S) then<br> &nbsp; &nbsp;for I := count-1 downto 0 do<br> &nbsp; &nbsp; &nbsp;D := S<br> &nbsp;else<br> &nbsp; &nbsp;for I := 0 to count-1 do<br> &nbsp; &nbsp; &nbsp;D := S;<br>end;<br>{$ELSE}<br>asm<br>{ &nbsp; &nbsp; -&gt;EAX &nbsp; &nbsp; Pointer to source &nbsp; &nbsp; &nbsp; }<br>{ &nbsp; &nbsp; &nbsp; EDX &nbsp; &nbsp; Pointer to destination &nbsp;}<br>{ &nbsp; &nbsp; &nbsp; ECX &nbsp; &nbsp; Count &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br><br> &nbsp; &nbsp; &nbsp; &nbsp;PUSH &nbsp; &nbsp;ESI<br> &nbsp; &nbsp; &nbsp; &nbsp;PUSH &nbsp; &nbsp;EDI<br><br> &nbsp; &nbsp; &nbsp; &nbsp;MOV &nbsp; &nbsp; ESI,EAX<br> &nbsp; &nbsp; &nbsp; &nbsp;MOV &nbsp; &nbsp; EDI,EDX<br><br> &nbsp; &nbsp; &nbsp; &nbsp;MOV &nbsp; &nbsp; EAX,ECX<br><br> &nbsp; &nbsp; &nbsp; &nbsp;CMP &nbsp; &nbsp; EDI,ESI<br> &nbsp; &nbsp; &nbsp; &nbsp;JA &nbsp; &nbsp; &nbsp;@@down<br> &nbsp; &nbsp; &nbsp; &nbsp;JE &nbsp; &nbsp; &nbsp;@@exit<br><br> &nbsp; &nbsp; &nbsp; &nbsp;SAR &nbsp; &nbsp; ECX,2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { copy count DIV 4 dwords &nbsp; &nbsp; &nbsp; }<br> &nbsp; &nbsp; &nbsp; &nbsp;JS &nbsp; &nbsp; &nbsp;@@exit<br><br> &nbsp; &nbsp; &nbsp; &nbsp;REP &nbsp; &nbsp; MOVSD<br><br> &nbsp; &nbsp; &nbsp; &nbsp;MOV &nbsp; &nbsp; ECX,EAX<br> &nbsp; &nbsp; &nbsp; &nbsp;AND &nbsp; &nbsp; ECX,03H<br> &nbsp; &nbsp; &nbsp; &nbsp;REP &nbsp; &nbsp; MOVSB &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { copy count MOD 4 bytes &nbsp; &nbsp; &nbsp; &nbsp;}<br> &nbsp; &nbsp; &nbsp; &nbsp;JMP &nbsp; &nbsp; @@exit<br><br>@@down:<br> &nbsp; &nbsp; &nbsp; &nbsp;LEA &nbsp; &nbsp; ESI,[ESI+ECX-4] { point ESI to last dword of source &nbsp; &nbsp; }<br> &nbsp; &nbsp; &nbsp; &nbsp;LEA &nbsp; &nbsp; EDI,[EDI+ECX-4] { point EDI to last dword of dest &nbsp; &nbsp; &nbsp; }<br><br> &nbsp; &nbsp; &nbsp; &nbsp;SAR &nbsp; &nbsp; ECX,2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { copy count DIV 4 dwords &nbsp; &nbsp; &nbsp; }<br> &nbsp; &nbsp; &nbsp; &nbsp;JS &nbsp; &nbsp; &nbsp;@@exit<br> &nbsp; &nbsp; &nbsp; &nbsp;STD<br> &nbsp; &nbsp; &nbsp; &nbsp;REP &nbsp; &nbsp; MOVSD<br><br> &nbsp; &nbsp; &nbsp; &nbsp;MOV &nbsp; &nbsp; ECX,EAX<br> &nbsp; &nbsp; &nbsp; &nbsp;AND &nbsp; &nbsp; ECX,03H &nbsp; &nbsp; &nbsp; &nbsp; { copy count MOD 4 bytes &nbsp; &nbsp; &nbsp; &nbsp;}<br> &nbsp; &nbsp; &nbsp; &nbsp;ADD &nbsp; &nbsp; ESI,4-1 &nbsp; &nbsp; &nbsp; &nbsp; { point to last byte of rest &nbsp; &nbsp;}<br> &nbsp; &nbsp; &nbsp; &nbsp;ADD &nbsp; &nbsp; EDI,4-1<br> &nbsp; &nbsp; &nbsp; &nbsp;REP &nbsp; &nbsp; MOVSB<br> &nbsp; &nbsp; &nbsp; &nbsp;CLD<br>@@exit:<br> &nbsp; &nbsp; &nbsp; &nbsp;POP &nbsp; &nbsp; EDI<br> &nbsp; &nbsp; &nbsp; &nbsp;POP &nbsp; &nbsp; ESI<br>end;<br>{$ENDIF}
 
楼主没明白<br><br>用字符串才用 StrCopy StrLCopy<br><br>别的就用 CompMemory<br>或 Move
 
直接用CopyMemory更快
 
目的是:字符数组A:array[0..10000]复制到字符数组B:array[0..10000],因为A中可能有NULL的字符,所以不能直接用StrCopy 和 StrLCopy .现在是用<br> for s:=0 to 10000 do<br> &nbsp;b:=a;<br>怎么说都比CompMemory或 Move 简单.用StrCopy 和 StrLCopy 是全汇编应该会快点.
 
请汇编高手帮忙改改。
 
维数、大小相同的字符数组可以直接赋值的。
 

Similar threads

I
回复
0
查看
535
import
I
I
回复
0
查看
739
import
I
I
回复
0
查看
719
import
I
I
回复
0
查看
805
import
I
I
回复
0
查看
670
import
I
后退
顶部