1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-22 02:29:29 +00:00

Optimization of two string functions (size & speed).

This commit is contained in:
IrgendwerA8 2017-02-25 20:19:34 +01:00
parent 97e64c388c
commit 6afcc370ed
3 changed files with 136 additions and 52 deletions

View File

@ -1,5 +1,6 @@
;
; Ullrich von Bassewitz, 31.05.1998
; Christian Krueger: 2013-Jul-24, minor optimization
;
; char* strcat (char* dest, const char* src);
;
@ -12,44 +13,35 @@ _strcat:
sta ptr1 ; Save src
stx ptr1+1
jsr popax ; Get dest
sta ptr2
stx ptr2+1
sta tmp3 ; Remember for function return
ldy #0
tay
lda #0
sta ptr2 ; access from page start, y contains low byte
stx ptr2+1
; find end of dest
sc1: lda (ptr2),y
beq sc2
findEndOfDest:
lda (ptr2),y
beq endOfDestFound
iny
bne sc1
bne findEndOfDest
inc ptr2+1
bne sc1
bne findEndOfDest
; end found, get offset in y into pointer
endOfDestFound:
sty ptr2 ; advance pointer to last y position
ldy #0 ; reset new y-offset
sc2: tya
clc
adc ptr2
sta ptr2
bcc sc3
inc ptr2+1
; copy src
sc3: ldy #0
sc4: lda (ptr1),y
copyByte:
lda (ptr1),y
sta (ptr2),y
beq sc5
beq done
iny
bne sc4
bne copyByte
inc ptr1+1
inc ptr2+1
bne sc4
bne copyByte ; like bra here
; done, return pointer to dest
sc5: lda tmp3 ; X does still contain high byte
; return pointer to dest
done: lda tmp3 ; X does still contain high byte
rts

View File

@ -1,5 +1,6 @@
;
; Ullrich von Bassewitz, 31.05.1998
; Christian Krueger, 2013-Aug-04, minor optimization
;
; const char* strchr (const char* s, int c);
;
@ -9,40 +10,38 @@
.importzp ptr1, tmp1
_strchr:
sta tmp1 ; Save c
jsr popax ; get s
sta ptr1
stx ptr1+1
ldy #0
sta tmp1 ; Save c
jsr popax ; get s
tay ; low byte of pointer to y
stx ptr1+1
lda #0
sta ptr1 ; ptr access page wise
Loop: lda (ptr1),y ; Get next char
beq EOS ; Jump on end of string
cmp tmp1 ; Found?
beq Found ; Jump if yes
Loop: lda (ptr1),y ; Get next char
beq EOS ; Jump on end of string
cmp tmp1 ; Found?
beq Found ; Jump if yes
iny
bne Loop
inc ptr1+1
bne Loop ; Branch always
bne Loop
inc ptr1+1
bne Loop ; Branch always
; End of string. Check if we're searching for the terminating zero
EOS: lda tmp1 ; Get the char we're searching for
bne NotFound ; Jump if not searching for terminator
EOS:
lda tmp1 ; Get the char we're searching for
bne NotFound ; Jump if not searching for terminator
; Found. Calculate pointer to c.
; Found. Set pointer to c.
Found: ldx ptr1+1 ; Load high byte of pointer
tya ; Low byte offset
clc
adc ptr1
bcc Found1
inx
Found1: rts
Found:
ldx ptr1+1 ; Load high byte of pointer
tya ; low byte is in y
rts
; Not found, return NULL
NotFound:
lda #0
lda #0
tax
rts

View File

@ -0,0 +1,93 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SourceStringSize 257 // test correct page passing (>256)
static char SourceString[SourceStringSize+1]; // +1 room for terminating null
static char DestinationString[2*SourceStringSize+1]; // will contain two times the source buffer
int main (void)
{
unsigned i,j;
char* p;
/* Print a header */
printf ("strcat(): ");
for (i=0; i < SourceStringSize; ++i)
SourceString[i] = (i%128)+1;
SourceString[i] = 0;
if (strlen(SourceString) != SourceStringSize)
{
printf ("Fail: Source string initialization or 'strlen()' problem!\n");
printf ("Expected length: %u but is %u!\n", SourceStringSize, strlen(SourceString));
exit (EXIT_FAILURE);
}
/* Ensure empty destination string */
DestinationString[0] = 0;
if (strlen(DestinationString) != 0)
{
printf ("Fail: Destination string initialization or 'strlen()' problem!\n");
printf ("Expected length: %u but is %u!\n", 0, strlen(DestinationString));
exit (EXIT_FAILURE);
}
/* Test concatenation to empty buffer */
p = strcat(DestinationString, SourceString);
if (strlen(DestinationString) != SourceStringSize)
{
printf ("Fail: String concatenation to empty buffer!\n");
printf ("Expected length: %u but is %u!\n", SourceStringSize, strlen(DestinationString));
exit (EXIT_FAILURE);
}
/* Test concatenation to non empty buffer */
p = strcat(DestinationString, SourceString);
if (strlen(DestinationString) != 2*SourceStringSize)
{
printf ("Fail: String concatenation to non-empty buffer!\n");
printf ("Expected length: %u but is %u!\n", 2*SourceStringSize, strlen(DestinationString));
exit (EXIT_FAILURE);
}
/* Test return value */
if (p != DestinationString)
{
printf ("Invalid return value!\n");
exit (EXIT_FAILURE);
}
/* Test contents */
for(j=0; j <2; ++j)
for(i=0; i < SourceStringSize; ++i)
{
unsigned position = j*SourceStringSize+i;
unsigned current = DestinationString[position];
unsigned expected = (i%128)+1;
if (current != expected)
{
printf ("Fail: Unexpected destination buffer contents at position %u!\n", position);
printf ("Expected %u, but is %u!\n", expected, current);
exit (EXIT_FAILURE);
}
}
/* Test passed */
printf ("Passed\n");
return EXIT_SUCCESS;
}