|
@@ -18,75 +18,90 @@
|
|
|
function strpas(p : pchar) : string;
|
|
|
begin
|
|
|
asm
|
|
|
+ movl p,%esi
|
|
|
movl __RESULT,%edi
|
|
|
- movb $1,%cl
|
|
|
+ movl %esi,%edx
|
|
|
+ movl $1,%ecx
|
|
|
+ andl $0x0fffffff8,%esi
|
|
|
+ // skip length byte
|
|
|
+ incl %edi
|
|
|
+ subl %esi,%edx
|
|
|
+ jz .LStrPasAligned
|
|
|
movl p,%esi
|
|
|
- // skip length byte -> align dest to multiple of 4
|
|
|
-.LStrCopyAlignLoop:
|
|
|
+ // align source to multiple of 4 (not dest, because we can't read past
|
|
|
+ // the end of the source, since that may be past the end of the heap
|
|
|
+ // -> sigsegv!!)
|
|
|
+.LStrPasAlignLoop:
|
|
|
movb (%esi),%al
|
|
|
- incl %edi
|
|
|
incl %esi
|
|
|
testb %al,%al
|
|
|
- jz .LStrCopyDone
|
|
|
- incb %cl
|
|
|
- movb %al,(%edi)
|
|
|
- cmpb $4,%cl
|
|
|
- jne .LStrCopyAlignLoop
|
|
|
+ jz .LStrPasDone
|
|
|
incl %edi
|
|
|
- .align 16
|
|
|
-.LStrCopyAligned:
|
|
|
+ incb %cl
|
|
|
+ decb %dl
|
|
|
+ movb %al,-1(%edi)
|
|
|
+ jne .LStrPasAlignLoop
|
|
|
+ .balign 16
|
|
|
+.LStrPasAligned:
|
|
|
movl (%esi),%eax
|
|
|
addl $4,%esi
|
|
|
// this won't overwrite data since the result = 255 char string
|
|
|
+ // and we never process more than the first 255 chars of p
|
|
|
movl %eax,(%edi)
|
|
|
testl $0x0ff,%eax
|
|
|
- jz .LStrCopyDone
|
|
|
+ jz .LStrPasDone
|
|
|
+ incl %ecx
|
|
|
testl $0x0ff00,%eax
|
|
|
- jz .LStrCopyByte
|
|
|
+ jz .LStrPasDone
|
|
|
+ incl %ecx
|
|
|
testl $0x0ff0000,%eax
|
|
|
- jz .LStrCopyWord
|
|
|
+ jz .LStrPasDone
|
|
|
+ incl %ecx
|
|
|
testl $0x0ff000000,%eax
|
|
|
- jz .LStrCopy3Bytes
|
|
|
+ jz .LStrPasDone
|
|
|
+ incl %ecx
|
|
|
addl $4,%edi
|
|
|
- addb $4,%cl
|
|
|
- // since ecx = 4 at the start of the loop, it will always count
|
|
|
- // upto exactly 0
|
|
|
- jnz .LStrCopyAligned
|
|
|
- jmp .LStrCopyDone
|
|
|
-.LStrCopy3Bytes:
|
|
|
- addb $3,%cl
|
|
|
- jmp .LStrCopyDone
|
|
|
-.LStrCopyWord:
|
|
|
- addb $2,%cl
|
|
|
- jmp .LStrCopyDone
|
|
|
-.LStrCopyByte:
|
|
|
+ cmpl $252,%ecx
|
|
|
+ jbe .LStrPasAligned
|
|
|
+ testb %cl,%cl
|
|
|
+ jz .LStrPasDone
|
|
|
+ movl (%esi),%eax
|
|
|
+.LStrPasEndLoop:
|
|
|
+ testb %al,%al
|
|
|
+ jz .LStrPasDone
|
|
|
+ movb %al,(%edi)
|
|
|
+ shrl $8,%eax
|
|
|
+ incl %edi
|
|
|
incb %cl
|
|
|
-.LStrCopyDone:
|
|
|
+ jnz .LStrPasEndLoop
|
|
|
+.LStrPasDone:
|
|
|
movl __RESULT,%edi
|
|
|
addb $255,%cl
|
|
|
movb %cl,(%edi)
|
|
|
-end ['EAX','ECX','ESI','EDI'];
|
|
|
+end ['EAX','ECX','EDX','ESI','EDI'];
|
|
|
end;
|
|
|
|
|
|
function strpcopy(d : pchar;const s : string) : pchar;assembler;
|
|
|
asm
|
|
|
pushl %esi // Save ESI
|
|
|
cld
|
|
|
- movl d,%edi // load destination address
|
|
|
movl s,%esi // Load Source adress
|
|
|
- lodsb // load length in ECX
|
|
|
- movzbl %al,%ecx
|
|
|
+ movl d,%edi // load destination address
|
|
|
+ movzbl (%esi),%ecx // load length in ECX
|
|
|
+ incl %esi
|
|
|
rep
|
|
|
movsb
|
|
|
- xorb %al,%al // Set #0
|
|
|
- stosb
|
|
|
+ movb $0,(%edi)
|
|
|
movl d,%eax // return value to EAX
|
|
|
popl %esi
|
|
|
end ['EDI','EAX','ECX'];
|
|
|
|
|
|
{
|
|
|
$Log$
|
|
|
- Revision 1.14 2000-06-30 12:20:20 jonas
|
|
|
+ Revision 1.15 2000-07-01 10:52:12 jonas
|
|
|
+ * fixed reading past end-of-heap again (correctly this time I hope)
|
|
|
+
|
|
|
+ Revision 1.14 2000/06/30 12:20:20 jonas
|
|
|
* strpas is again slightly slower, but won't crash anymore if a pchar
|
|
|
is passed to it that starts less than 4 bbytes from the heap end
|
|
|
|