mirror of
https://github.com/cc65/cc65.git
synced 2024-12-30 20:29:25 +00:00
98 lines
2.0 KiB
ArmAsm
98 lines
2.0 KiB
ArmAsm
|
;
|
||
|
; Ullrich von Bassewitz, 11.12.1998
|
||
|
;
|
||
|
; char* strstr (const char* haystack, const char* needle);
|
||
|
;
|
||
|
|
||
|
.export _strstr
|
||
|
.import popax
|
||
|
.importzp ptr1, ptr2, ptr3, ptr4, tmp1
|
||
|
|
||
|
_strstr:
|
||
|
sta ptr2 ; Save needle
|
||
|
stx ptr2+1
|
||
|
sta ptr4 ; Setup temp copy for later
|
||
|
|
||
|
jsr popax ; Get haystack
|
||
|
sta ptr1
|
||
|
stx ptr1+1 ; Save haystack
|
||
|
|
||
|
; If needle is empty, return haystack
|
||
|
|
||
|
ldy #$00
|
||
|
lda (ptr2),y ; Get first byte of needle
|
||
|
beq @Found ; Needle is empty --> we're done
|
||
|
|
||
|
; Search for the beginning of the string (this is not an optimal search
|
||
|
; strategy [in fact, it's pretty dumb], but it's simple to implement).
|
||
|
|
||
|
sta tmp1 ; Save start of needle
|
||
|
@L1: lda (ptr1),y ; Get next char from haystack
|
||
|
beq @NotFound ; Jump if end
|
||
|
cmp tmp1 ; Start of needle found?
|
||
|
beq @L2 ; Jump if so
|
||
|
iny ; Next char
|
||
|
bne @L1
|
||
|
inc ptr1+1 ; Bump high byte
|
||
|
bne @L1 ; Branch always
|
||
|
|
||
|
; We found the start of needle in haystack
|
||
|
|
||
|
@L2: tya ; Get offset
|
||
|
clc
|
||
|
adc ptr1
|
||
|
sta ptr1 ; Make ptr1 point to start
|
||
|
bcc @L3
|
||
|
inc ptr1+1
|
||
|
|
||
|
; ptr1 points to the start of needle now. Setup temporary pointers for the
|
||
|
; search. The low byte of ptr4 is already set.
|
||
|
|
||
|
@L3: sta ptr3
|
||
|
lda ptr1+1
|
||
|
sta ptr3+1
|
||
|
lda ptr2+1
|
||
|
sta ptr4+1
|
||
|
ldy #1 ; First char is identical, so start on second
|
||
|
|
||
|
; Do the compare
|
||
|
|
||
|
@L4: lda (ptr4),y ; Get char from needle
|
||
|
beq @Found ; Jump if end of needle (-> found)
|
||
|
cmp (ptr3),y ; Compare with haystack
|
||
|
bne @L5 ; Jump if not equal
|
||
|
iny ; Next char
|
||
|
bne @L4
|
||
|
inc ptr3+1
|
||
|
inc ptr4+1 ; Bump hi byte of pointers
|
||
|
bne @L4 ; Next char (branch always)
|
||
|
|
||
|
; The strings did not compare equal, search next start of needle
|
||
|
|
||
|
@L5: ldy #1 ; Start after this char
|
||
|
bne @L1 ; Branch always
|
||
|
|
||
|
; We found the start of needle
|
||
|
|
||
|
@Found: lda ptr1
|
||
|
ldx ptr1+1
|
||
|
rts
|
||
|
|
||
|
; We reached end of haystack without finding needle
|
||
|
|
||
|
@NotFound:
|
||
|
lda #$00 ; return NULL
|
||
|
tax
|
||
|
rts
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|