~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to strings/strings.asm

  • Committer: Monty Taylor
  • Date: 2008-10-16 06:32:30 UTC
  • mto: (511.1.5 codestyle)
  • mto: This revision was merged to the branch mainline in revision 521.
  • Revision ID: monty@inaugust.com-20081016063230-4brxsra0qsmsg84q
Added -Wunused-macros.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
; Copyright (C) 2000, 2003 MySQL AB
2
 
3
 
; This library is free software; you can redistribute it and/or
4
 
; modify it under the terms of the GNU Library General Public
5
 
; License as published by the Free Software Foundation; version 2
6
 
; of the License.
7
 
8
 
; This library is distributed in the hope that it will be useful,
9
 
; but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11
 
; Library General Public License for more details.
12
 
13
 
; You should have received a copy of the GNU Library General Public
14
 
; License along with this library; if not, write to the Free
15
 
; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
16
 
; MA 02111-1307, USA
17
 
 
18
 
; Note that if you don't have a macro assembler (like MASM) to compile
19
 
; this file, you can instead compile all *.c files in the string
20
 
; directory.
21
 
 
22
 
        TITLE   Stringfunctions that we use often at MSDOS / Intel 8086
23
 
 
24
 
ifndef M_I386
25
 
        .8087
26
 
        DOSSEG
27
 
        .MODEL LARGE
28
 
        .CODE
29
 
 
30
 
        ;
31
 
        ; Some macros
32
 
        ;
33
 
 
34
 
q_movs  MACRO                           ; as rep movsb but quicker
35
 
        shr     cx,1
36
 
        rep     movsw                   ; Move 2 bytes at a time
37
 
        adc     cx,cx
38
 
        rep     movsb                   ; Move last byte if any
39
 
        ENDM
40
 
 
41
 
q_stos  MACRO                           ; as rep stosb but quicker
42
 
        mov     ah,al                   ; For word store
43
 
        shr     cx,1
44
 
        rep     stosw                   ; Move 2 bytes at a time
45
 
        adc     cx,cx
46
 
        rep     stosb                   ; Move last byte if any
47
 
        ENDM
48
 
 
49
 
ifndef  ZTC                             ; If not using ZORTECH compiler
50
 
        ;
51
 
        ; Compare memory
52
 
        ; Args: s1,s2,length
53
 
        ;
54
 
 
55
 
        PUBLIC  _bcmp
56
 
_bcmp   PROC
57
 
        mov     bx,bp                   ; Save bp
58
 
        mov     dx,di                   ; Save di
59
 
        mov     bp,sp
60
 
        push    ds
61
 
        push    si
62
 
        les     di,DWORD PTR [bp+8]     ; s2
63
 
        lds     si,DWORD PTR [bp+4]     ; s1
64
 
        mov     cx,WORD PTR [bp+12]     ; Length of memory-area
65
 
        jcxz    @F                      ; Length = 0, return same
66
 
;       cld                             ; Work uppward
67
 
        repe    cmpsb                   ; Compare strings
68
 
        jz      @F                      ; Match found
69
 
        inc     cx                      ; return matchpoint +1
70
 
@@:     mov     ax,cx                   ; Return 0 if match, else pos from end
71
 
        pop     si
72
 
        pop     ds
73
 
        mov     di,dx
74
 
        mov     bp,bx
75
 
        ret
76
 
_bcmp   ENDP
77
 
 
78
 
        ;
79
 
        ; Find a char in a string
80
 
        ; Arg: str,char
81
 
        ; Ret: pointer to found char or NullS
82
 
        ;
83
 
 
84
 
ifdef better_stringfunctions            ; Breaks window linkage (broken linking)
85
 
 
86
 
        PUBLIC  _strchr
87
 
_strchr PROC
88
 
        mov     bx,bp                   ; Save bp and di
89
 
        mov     dx,di
90
 
        mov     bp,sp
91
 
        les     di,DWORD PTR [bp+4]     ; str
92
 
        mov     ah,BYTE PTR [bp+8]      ; search
93
 
        xor     al,al                   ; for scasb to find end
94
 
 
95
 
@@:     cmp     ah,es:[di]
96
 
        jz      @F                      ; Found char
97
 
        scasb
98
 
        jnz     @B                      ; Not end
99
 
        xor     di,di                   ; Not found
100
 
        mov     es,di
101
 
@@:     mov     ax,di
102
 
        mov     di,dx                   ; Restore
103
 
        mov     dx,es                   ; Seg adr
104
 
        mov     bp,bx                   ; Restore
105
 
        ret
106
 
_strchr ENDP
107
 
 
108
 
        ;
109
 
        ; Find length of string
110
 
        ; arg: str
111
 
        ; ret: length
112
 
        ;
113
 
 
114
 
        PUBLIC  _strlen
115
 
_strlen PROC
116
 
        mov     bx,sp
117
 
        mov     dx,di
118
 
        les     di,DWORD PTR ss:[bx+4]  ; Str
119
 
        xor     al,al                   ; Find end of string
120
 
        mov     cx,-1
121
 
;       cld
122
 
        repne   scasb                   ; Find strend or length
123
 
        inc     cx                      ; Calc strlength
124
 
        not     cx
125
 
        mov     ax,cx
126
 
        mov     di,dx                   ; Restore register
127
 
        ret
128
 
_strlen ENDP
129
 
 
130
 
endif
131
 
 
132
 
        ;
133
 
        ; Move a string
134
 
        ; arg: dst,src
135
 
        ; ret: end-null of to
136
 
        ;
137
 
 
138
 
        PUBLIC  _strmov
139
 
_strmov PROC
140
 
        mov     bx,bp
141
 
        mov     cx,si
142
 
        mov     bp,sp
143
 
        push    ds
144
 
        push    di
145
 
        les     di,DWORD PTR [bp+4]     ; dst
146
 
        lds     si,DWORD PTR [bp+8]     ; src
147
 
;       cld
148
 
@@:     mov     al,ds:[si]
149
 
        movsb                           ; move arg
150
 
        and     al,al
151
 
        jnz     @B                      ; Not last
152
 
        lea     ax,WORD PTR [di-1]      ; Set DX:AX to point at last null
153
 
        mov     dx,es
154
 
        pop     di
155
 
        pop     ds
156
 
        mov     si,cx
157
 
        mov     bp,bx
158
 
        ret
159
 
_strmov ENDP
160
 
 
161
 
        ;
162
 
        ; Fill a area of memory with a walue
163
 
        ; Args: to,length,fillchar
164
 
        ;
165
 
 
166
 
        PUBLIC  _bfill
167
 
_bfill  PROC
168
 
        mov     bx,sp                   ; Get args through BX
169
 
        mov     al,BYTE PTR ss:[bx+10]  ; Fill
170
 
bfill_10:
171
 
        mov     dx,di                   ; Save di
172
 
        les     di,DWORD PTR ss:[bx+4]  ; Memory pointer
173
 
        mov     cx,WORD PTR ss:[bx+8]   ; Length
174
 
;       cld
175
 
        q_stos
176
 
        mov     di,dx
177
 
        ret
178
 
_bfill  ENDP
179
 
 
180
 
        ;
181
 
        ; Fill a area with null
182
 
        ; Args: to,length
183
 
 
184
 
        PUBLIC  _bzero
185
 
_bzero  PROC
186
 
        mov     bx,sp                   ; Get args through BX
187
 
        mov     al,0                    ; Fill with null
188
 
        jmp     short bfill_10
189
 
_bzero  ENDP
190
 
 
191
 
endif   ; ZTC
192
 
 
193
 
        ;
194
 
        ; Move a memory area
195
 
        ; Args: to,from,length
196
 
        ;
197
 
 
198
 
        PUBLIC  _bmove
199
 
_bmove  PROC
200
 
        mov     bx,bp
201
 
        mov     dx,di
202
 
        mov     ax,si
203
 
        mov     bp,sp
204
 
        push    ds
205
 
        lds     si,DWORD PTR [bp+8]     ; from
206
 
        les     di,DWORD PTR [bp+4]     ; to
207
 
        mov     cx,WORD PTR [bp+12]     ; Length of memory-area
208
 
;       cld                             ; Work uppward
209
 
        rep     movsb                   ; Not q_movs because overlap ?
210
 
        pop     ds
211
 
        mov     si,ax
212
 
        mov     di,dx
213
 
        mov     bp,bx
214
 
        ret
215
 
_bmove  ENDP
216
 
 
217
 
        ;
218
 
        ; Move a alligned, not overlapped, by (long) divided memory area
219
 
        ; Args: to,from,length
220
 
        ;
221
 
 
222
 
        PUBLIC  _bmove_align
223
 
_bmove_align    PROC
224
 
        mov     bx,bp
225
 
        mov     dx,di
226
 
        mov     ax,si
227
 
        mov     bp,sp
228
 
        push    ds
229
 
        lds     si,DWORD PTR [bp+8]     ; from
230
 
        les     di,DWORD PTR [bp+4]     ; to
231
 
        mov     cx,WORD PTR [bp+12]     ; Length of memory-area
232
 
;       cld                             ; Work uppward
233
 
        inc     cx                      ; fix if not divisible with word
234
 
        shr     cx,1
235
 
        rep     movsw                   ; Move 2 bytes at a time
236
 
        pop     ds
237
 
        mov     si,ax
238
 
        mov     di,dx
239
 
        mov     bp,bx
240
 
        ret
241
 
_bmove_align    ENDP
242
 
 
243
 
        ;
244
 
        ; Move a string from higher to lower
245
 
        ; Arg from+1,to+1,length
246
 
        ;
247
 
 
248
 
        PUBLIC  _bmove_upp
249
 
_bmove_upp      PROC
250
 
        mov     bx,bp
251
 
        mov     dx,di
252
 
        mov     ax,si
253
 
        mov     bp,sp
254
 
        push    ds
255
 
        lds     si,DWORD PTR [bp+8]     ; from
256
 
        les     di,DWORD PTR [bp+4]     ; to
257
 
        mov     cx,WORD PTR [bp+12]     ; Length of memory-area
258
 
        dec     di                      ; Don't move last arg
259
 
        dec     si
260
 
        std                             ; Work downward
261
 
        rep     movsb                   ; Not q_movs because overlap ?
262
 
        cld                             ; C compilator want cld
263
 
        pop     ds
264
 
        mov     si,ax
265
 
        mov     di,dx
266
 
        mov     bp,bx
267
 
        ret
268
 
_bmove_upp ENDP
269
 
 
270
 
        ;
271
 
        ; Append fillchars to string
272
 
        ; Args: dest,len,fill
273
 
        ;
274
 
 
275
 
        PUBLIC  _strappend
276
 
_strappend      PROC
277
 
        mov     bx,bp
278
 
        mov     dx,di
279
 
        mov     bp,sp
280
 
        les     di,DWORD PTR [bp+4]     ; Memory pointer
281
 
        mov     cx,WORD PTR [bp+8]      ; Length
282
 
        sub     al,al                   ; Find end of string
283
 
;       cld
284
 
        repne   scasb
285
 
        jnz     sa_99                   ; String to long, shorten it
286
 
        mov     al,BYTE PTR [bp+10]     ; Fillchar
287
 
        dec     di                      ; Point at end null
288
 
        inc     cx                      ; rep made one dec for null-char
289
 
        q_stos                          ; Store al in string
290
 
sa_99:  mov     BYTE PTR es:[di],0      ; End of string
291
 
        mov     di,dx
292
 
        mov     bp,bx
293
 
        ret
294
 
_strappend      ENDP
295
 
 
296
 
        ;
297
 
        ; Find if string contains any char in another string
298
 
        ; Arg: str,set
299
 
        ; Ret: Pointer to first found char in str
300
 
        ;
301
 
 
302
 
        PUBLIC  _strcont
303
 
_strcont        PROC
304
 
        mov     bx,bp                   ; Save bp and di in regs
305
 
        mov     dx,di
306
 
        mov     bp,sp
307
 
        push    ds
308
 
        push    si
309
 
        lds     si,DWORD PTR [bp+4]     ; str
310
 
        les     di,DWORD PTR [bp+8]     ; Set
311
 
        mov     cx,di                   ; Save for loop
312
 
        xor     ah,ah                   ; For endtest
313
 
        jmp     sc_60
314
 
 
315
 
sc_10:  scasb
316
 
        jz      sc_fo                   ; Found char
317
 
sc_20:  cmp     ah,es:[di]              ; Test if null
318
 
        jnz     sc_10                   ; Not end of set yet
319
 
        inc     si                      ; Next char in str
320
 
        mov     di,cx                   ; es:di = Set
321
 
sc_60:  mov     al,ds:[si]              ; Test if this char exist
322
 
        and     al,al
323
 
        jnz     sc_20                   ; Not end of string
324
 
        sub     si,si                   ; Return Null
325
 
        mov     ds,si
326
 
sc_fo:  mov     ax,si                   ; Char found here
327
 
        mov     di,dx                   ; Restore
328
 
        mov     dx,ds                   ; Seg of found char
329
 
        pop     si
330
 
        pop     ds
331
 
        mov     bp,bx
332
 
        ret
333
 
_strcont        ENDP
334
 
 
335
 
        ;
336
 
        ; Found end of string
337
 
        ; Arg: str
338
 
        ; ret: Pointer to end null
339
 
        ;
340
 
 
341
 
        PUBLIC  _strend
342
 
_strend PROC
343
 
        mov     bx,sp
344
 
        mov     dx,di                   ; Save
345
 
        les     di,DWORD PTR ss:[bx+4]  ; str
346
 
        mov     cx,-1
347
 
        sub     al,al                   ; Find end of string
348
 
;       cld
349
 
        repne   scasb
350
 
        lea     ax,WORD PTR [di-1]      ; Endpos i DX:AX
351
 
        mov     di,dx                   ; Restore
352
 
        mov     dx,es
353
 
        ret
354
 
_strend ENDP
355
 
 
356
 
        ;
357
 
        ; Make a string with len fill-chars and endnull
358
 
        ; Args: dest,len,fill
359
 
        ; Ret:  dest+len
360
 
        ;
361
 
 
362
 
        PUBLIC  _strfill
363
 
_strfill        PROC
364
 
        mov     bx,bp                   ; Save sp
365
 
        mov     bp,sp
366
 
        push    di
367
 
        les     di,DWORD PTR [bp+4]     ; Memory pointer
368
 
        mov     cx,WORD PTR [bp+8]      ; Length
369
 
        mov     al,BYTE PTR [bp+10]     ; Fill
370
 
;       cld
371
 
        q_stos
372
 
        mov     BYTE PTR es:[di],0      ; End NULL
373
 
        mov     ax,di                   ; End i DX:AX
374
 
        mov     dx,es
375
 
        pop     di
376
 
        mov     bp,bx
377
 
        ret
378
 
_strfill        ENDP
379
 
 
380
 
        ;
381
 
        ; Find a char in or end of a string
382
 
        ; Arg: str,char
383
 
        ; Ret: pointer to found char or NullS
384
 
        ;
385
 
 
386
 
        PUBLIC  _strcend
387
 
_strcend        PROC
388
 
        mov     bx,bp                   ; Save bp and di
389
 
        mov     dx,di
390
 
        mov     bp,sp
391
 
        les     di,DWORD PTR [bp+4]     ; str
392
 
        mov     ah,BYTE PTR [bp+8]      ; search
393
 
        xor     al,al                   ; for scasb to find end
394
 
 
395
 
@@:     cmp     ah,es:[di]
396
 
        jz      @F                      ; Found char
397
 
        scasb
398
 
        jnz     @B                      ; Not end
399
 
        dec     di                      ; Not found, point at end of string
400
 
@@:     mov     ax,di
401
 
        mov     di,dx                   ; Restore
402
 
        mov     dx,es                   ; Seg adr
403
 
        mov     bp,bx                   ; Restore
404
 
        ret
405
 
_strcend        ENDP
406
 
 
407
 
        ;
408
 
        ; Test if string has a given suffix
409
 
        ;
410
 
 
411
 
PUBLIC  _is_prefix
412
 
_is_prefix PROC
413
 
        mov     dx,di                   ; Save di
414
 
        mov     bx,sp                   ; Arguments through bx
415
 
        push    ds
416
 
        push    si
417
 
        les     di,DWORD PTR ss:[bx+8]  ; s2
418
 
        lds     si,DWORD PTR ss:[bx+4]  ; s1
419
 
        mov     ax,1                    ; Ok and zero-test
420
 
;       cld                             ; Work uppward
421
 
@@:     cmp     ah,es:[di]
422
 
        jz      suf_ok                  ; End of string; found suffix
423
 
        cmpsb                           ; Compare strings
424
 
        jz      @B                      ; Same, possible prefix
425
 
        xor     ax,ax                   ; Not suffix
426
 
suf_ok: pop     si
427
 
        pop     ds
428
 
        mov     di,dx
429
 
        ret
430
 
_is_prefix ENDP
431
 
 
432
 
        ;
433
 
        ; Find a substring in string
434
 
        ; Arg: str,search
435
 
        ;
436
 
 
437
 
        PUBLIC  _strstr
438
 
_strstr PROC
439
 
        mov     bx,bp
440
 
        mov     bp,sp
441
 
        push    ds
442
 
        push    di
443
 
        push    si
444
 
        lds     si,DWORD PTR [bp+4]     ; str
445
 
        les     di,DWORD PTR [bp+8]     ; search
446
 
        mov     cx,di
447
 
        inc     cx                      ; CX = search+1
448
 
        mov     ah,es:[di]              ; AH = First char in search
449
 
        jmp     sf_10
450
 
 
451
 
sf_00:  mov     si,dx                   ; si = Current str-pos
452
 
sf_10:  mov     al,ds:[si]              ; Test if this char exist
453
 
        and     al,al
454
 
        jz      sf_90                   ; End of string, didn't find search
455
 
        inc     si
456
 
        cmp     al,ah
457
 
        jnz     sf_10                   ; Didn't find first char, continue
458
 
        mov     dx,si                   ; Save str-pos in DX
459
 
        mov     di,cx
460
 
sf_20:  cmp     BYTE PTR es:[di],0
461
 
        jz      sf_fo                   ; Found substring
462
 
        cmpsb
463
 
        jz      sf_20                   ; Char ok
464
 
        jmp     sf_00                   ; Next str-pos
465
 
 
466
 
sf_90:  sub     dx,dx                   ; Return Null
467
 
        mov     ds,dx
468
 
        inc     dx                      ; Because of following dec
469
 
sf_fo:  mov     ax,dx                   ; Char found here
470
 
        dec     ax                      ; Pointed one after
471
 
        mov     dx,ds
472
 
        pop     si
473
 
        pop     di                      ; End
474
 
        pop     ds
475
 
        mov     bp,bx
476
 
        ret
477
 
_strstr ENDP
478
 
 
479
 
        ;
480
 
        ; Make a string of len length from another string
481
 
        ; Arg: dst,src,length
482
 
        ; ret: end of dst
483
 
        ;
484
 
 
485
 
        PUBLIC  _strmake
486
 
_strmake        PROC
487
 
        mov     bx,bp
488
 
        mov     bp,sp
489
 
        push    ds
490
 
        push    di
491
 
        push    si
492
 
        les     di,DWORD PTR [bp+4]     ; dst
493
 
        lds     si,DWORD PTR [bp+8]     ; src
494
 
        mov     cx,WORD PTR [bp+12]     ; Length of memory-area
495
 
        xor     al,al                   ; For test of end-null
496
 
        jcxz    sm_90                   ; Nothing to move, put zero at end.
497
 
;       cld                             ; Work uppward
498
 
 
499
 
@@:     cmp     al,ds:[si]              ; Next char to move
500
 
        movsb                           ; move arg
501
 
        jz      sm_99                   ; last char, we are ready
502
 
        loop    @B                      ; Continue moving
503
 
sm_90:  mov     BYTE PTR es:[di],al     ; Set end pos
504
 
        inc     di                      ; Fix that di points at end null
505
 
sm_99:  dec     di                      ; di points now at end null
506
 
        mov     ax,di                   ; Ret value in DX:AX
507
 
        mov     dx,es
508
 
        pop     si
509
 
        pop     di
510
 
        pop     ds
511
 
        mov     bp,bx
512
 
        ret
513
 
_strmake        ENDP
514
 
 
515
 
        ;
516
 
        ; Find length of string with maxlength
517
 
        ; arg: str,maxlength
518
 
        ; ret: length
519
 
        ;
520
 
 
521
 
        PUBLIC  _strnlen
522
 
_strnlen        PROC
523
 
        mov     bx,bp
524
 
        mov     bp,sp
525
 
        push    di
526
 
        les     di,DWORD PTR [bp+4]     ; Str
527
 
        mov     cx,WORD PTR [bp+8]      ; length
528
 
        mov     dx,di                   ; Save str to calc length
529
 
        jcxz    sn_10                   ; Length = 0
530
 
        xor     al,al                   ; Find end of string
531
 
;       cld
532
 
        repne   scasb                   ; Find strend or length
533
 
        jnz     sn_10
534
 
        dec     di                      ; DI points at last null
535
 
sn_10:  mov     ax,di
536
 
        sub     ax,dx                   ; Ax = length
537
 
        pop     di
538
 
        mov     bp,bx
539
 
        ret
540
 
_strnlen        ENDP
541
 
 
542
 
        ;
543
 
        ; Move a string with max len chars
544
 
        ; arg: dst,src,len
545
 
        ; ret: pos to first null or dst+len
546
 
 
547
 
        PUBLIC  _strnmov
548
 
_strnmov        PROC
549
 
        mov     bx,bp
550
 
        mov     bp,sp
551
 
        push    ds
552
 
        push    di
553
 
        push    si
554
 
        les     di,DWORD PTR [bp+4]     ; dst
555
 
        lds     si,DWORD PTR [bp+8]     ; src
556
 
        mov     cx,WORD PTR [bp+12]     ; length
557
 
        jcxz    snm_99                  ; Nothing to do
558
 
        xor     al,al                   ; For test of end-null
559
 
;       cld
560
 
 
561
 
@@:     cmp     al,ds:[si]              ; Next char to move
562
 
        movsb                           ; move arg
563
 
        jz      snm_20                  ; last char, fill with null
564
 
        loop    @B                      ; Continue moving
565
 
        inc     di                      ; Point two after last
566
 
snm_20: dec     di                      ; Point at first null (or last+1)
567
 
snm_99: mov     ax,di                   ; Pointer at last char
568
 
        mov     dx,es                   ; To-segment
569
 
        pop     si
570
 
        pop     di
571
 
        pop     ds
572
 
        mov     bp,bx                   ; Restore
573
 
        ret
574
 
_strnmov        ENDP
575
 
 
576
 
else    ; M_I386
577
 
 
578
 
include macros.asm
579
 
 
580
 
q_stos  MACRO                           ; as rep stosb but quicker, Uses edx
581
 
        mov     ah,al                   ;(2) Set up a 32 bit pattern.
582
 
        mov     edx,eax                 ;(2)
583
 
        shl     edx,16                  ;(3)
584
 
        or      eax,edx                 ;(2) EAX has the 32 bit pattern.
585
 
 
586
 
        mov     edx,ecx                 ;(2) Save the count of bytes.
587
 
        shr     ecx,2                   ;(2) Number of dwords.
588
 
        rep     stosd                   ;(5 + 5n)
589
 
        mov     cl,3                    ;(2)
590
 
        and     ecx,edx                 ;(2) Fill in the remaining odd bytes.
591
 
        rep     stosb                   ; Move last bytes if any
592
 
        ENDM
593
 
 
594
 
fix_es  MACRO   fix_cld                 ; Load ES if neaded
595
 
  ife ESeqDS
596
 
        mov     ax,ds
597
 
        mov     es,ax
598
 
  endif
599
 
  ifnb <fix_cld>
600
 
        cld
601
 
  endif
602
 
        ENDM
603
 
 
604
 
        ;
605
 
        ; Move a memory area
606
 
        ; Args: to,from,length
607
 
        ; Acts as one byte was moved a-time from dst to source.
608
 
        ;
609
 
 
610
 
        begcode bmove
611
 
        public  _bmove
612
 
_bmove  proc near
613
 
        fix_es  1
614
 
        mov     edx,edi
615
 
        mov     eax,esi
616
 
        mov     edi,P-SIZEPTR[esp]      ;p1
617
 
        mov     esi,P[esp]              ;p2
618
 
        mov     ecx,P+SIZEPTR[esp]
619
 
        rep     movsb                   ; Not q_movs because overlap ?
620
 
        mov     esi,eax
621
 
        mov     edi,edx
622
 
        ret
623
 
_bmove  ENDP
624
 
        endcode bmove
625
 
 
626
 
        ;
627
 
        ; Move a alligned, not overlapped, by (long) divided memory area
628
 
        ; Args: to,from,length
629
 
        ;
630
 
 
631
 
        begcode bmove_align
632
 
        public  _bmove_align
633
 
_bmove_align    proc near
634
 
        fix_es  1
635
 
        mov     edx,edi
636
 
        mov     eax,esi
637
 
        mov     edi,P-SIZEPTR[esp]      ;to
638
 
        mov     esi,P[esp]              ;from
639
 
        mov     ecx,P+SIZEPTR[esp]      ;length
640
 
        add     cx,3                    ;fix if not divisible with long
641
 
        shr     cx,2
642
 
        rep     movsd
643
 
        mov     esi,eax
644
 
        mov     edi,edx
645
 
        ret
646
 
_bmove_align    ENDP
647
 
        endcode bmove_align
648
 
 
649
 
        ;
650
 
        ; Move a string from higher to lower
651
 
        ; Arg from+1,to+1,length
652
 
        ;
653
 
 
654
 
        begcode bmove_upp
655
 
        public  _bmove_upp
656
 
_bmove_upp      proc near
657
 
        fix_es
658
 
        std                             ; Work downward
659
 
        mov     edx,edi
660
 
        mov     eax,esi
661
 
        mov     edi,P-SIZEPTR[esp]      ;p1
662
 
        mov     esi,P[esp]              ;p2
663
 
        mov     ecx,P+SIZEPTR[esp]
664
 
        dec     edi                     ; Don't move last arg
665
 
        dec     esi
666
 
        rep     movsb                   ; One byte a time because overlap !
667
 
        cld                             ; C compilator wants cld
668
 
        mov     esi,eax
669
 
        mov     edi,edx
670
 
        ret
671
 
_bmove_upp ENDP
672
 
        endcode bmove_upp
673
 
 
674
 
        ;
675
 
        ; Append fillchars to string
676
 
        ; Args: dest,len,fill
677
 
        ;
678
 
 
679
 
        begcode strappend
680
 
        public  _strappend
681
 
_strappend      proc near
682
 
        push    ebp
683
 
        mov     ebp,esp
684
 
        fix_es  1
685
 
        push    edi
686
 
        mov     edi,P[ebp]              ; Memory pointer
687
 
        mov     ecx,P+SIZEPTR[ebp]      ; Length
688
 
        clr     eax                     ; Find end of string
689
 
        repne   scasb
690
 
        jnz     sa_99                   ; String to long, shorten it
691
 
        movzx   eax,byte ptr P+(2*SIZEPTR)[ebp] ; Fillchar
692
 
        dec     edi                     ; Point at end null
693
 
        inc     ecx                     ; rep made one dec for null-char
694
 
        q_stos                          ; Store al in string
695
 
sa_99:  mov     BYTE PTR [edi],0        ; End of string
696
 
        pop     edi
697
 
        pop     ebp
698
 
        ret
699
 
_strappend      ENDP
700
 
        endcode strappend
701
 
 
702
 
        ;
703
 
        ; Find if string contains any char in another string
704
 
        ; Arg: str,set
705
 
        ; Ret: Pointer to first found char in str
706
 
        ;
707
 
 
708
 
        begcode strcont
709
 
        PUBLIC  _strcont
710
 
_strcont proc near
711
 
        push    ebp
712
 
        mov     ebp,esp
713
 
        fix_es  1
714
 
        mov     edx,edi
715
 
        push    esi
716
 
        mov     esi,P[ebp]              ; str
717
 
        mov     ecx,P+SIZEPTR[ebp]      ; Set
718
 
        clr     ah                      ; For endtest
719
 
        jmps    sc_60
720
 
 
721
 
sc_10:  scasb
722
 
        jz      sc_fo                   ; Found char
723
 
sc_20:  cmp     ah,[edi]                ; Test if null
724
 
        jnz     sc_10                   ; Not end of set yet
725
 
        inc     esi                     ; Next char in str
726
 
sc_60:  mov     edi,ecx                 ; edi = Set
727
 
        mov     al,[esi]                ; Test if this char exist
728
 
        and     al,al
729
 
        jnz     sc_20                   ; Not end of string
730
 
        clr     esi                     ; Return Null
731
 
sc_fo:  mov     eax,esi                 ; Char found here
732
 
        mov     edi,edx                 ; Restore
733
 
        pop     esi
734
 
        pop     ebp
735
 
        ret
736
 
_strcont        ENDP
737
 
        endcode strcont
738
 
 
739
 
        ;
740
 
        ; Found end of string
741
 
        ; Arg: str
742
 
        ; ret: Pointer to end null
743
 
        ;
744
 
 
745
 
        begcode strend
746
 
        public  _strend
747
 
_strend proc near
748
 
        fix_es  1
749
 
        mov     edx,edi                 ; Save
750
 
        mov     edi,P-SIZEPTR[esp]      ; str
751
 
        clr     eax                     ; Find end of string
752
 
        mov     ecx,eax
753
 
        dec     ecx                     ; ECX = -1
754
 
        repne   scasb
755
 
        mov     eax,edi
756
 
        dec     eax
757
 
        mov     edi,edx                 ; Restore
758
 
        ret
759
 
_strend endp
760
 
        endcode strend
761
 
 
762
 
        ;
763
 
        ; Make a string with len fill-chars and endnull
764
 
        ; Args: dest,len,fill
765
 
        ; Ret:  dest+len
766
 
        ;
767
 
 
768
 
        begcode strfill
769
 
        public  _strfill
770
 
_strfill proc near
771
 
        push    ebp
772
 
        mov     ebp,esp
773
 
        fix_es  1
774
 
        push    edi
775
 
        mov     edi,P[ebp]              ; Memory pointer
776
 
        mov     ecx,P+SIZEPTR[ebp]      ; Length
777
 
        movzx   eax,byte ptr P+(2*SIZEPTR)[ebp] ; Fill
778
 
        q_stos
779
 
        mov     BYTE PTR [edi],0        ; End NULL
780
 
        mov     eax,edi                 ; End i DX:AX
781
 
        pop     edi
782
 
        pop     ebp
783
 
        ret
784
 
_strfill endp
785
 
        endcode strfill
786
 
 
787
 
        ;
788
 
        ; Find a char in or end of a string
789
 
        ; Arg: str,char
790
 
        ; Ret: pointer to found char or NullS
791
 
        ;
792
 
 
793
 
        begcode strcend
794
 
        public  _strcend
795
 
_strcend proc near
796
 
        push    ebp
797
 
        mov     ebp,esp
798
 
        fix_es  1
799
 
        mov     edx,edi
800
 
        mov     edi,P[ebp]              ; str
801
 
        mov     ah,P+SIZEPTR[ebp]       ; search
802
 
        clr     al                      ; for scasb to find end
803
 
 
804
 
@@:     cmp     ah,[edi]
805
 
        jz      @F                      ; Found char
806
 
        scasb
807
 
        jnz     @B                      ; Not end
808
 
        dec     edi                     ; Not found, point at end of string
809
 
@@:     mov     eax,edi
810
 
        mov     edi,edx                 ; Restore
811
 
        pop     ebp
812
 
        ret
813
 
_strcend        ENDP
814
 
        endcode strcend
815
 
 
816
 
        ;
817
 
        ; Test if string has a given suffix
818
 
        ;
819
 
 
820
 
        begcode is_prefix
821
 
        public  _is_prefix
822
 
_is_prefix proc near
823
 
        fix_es  1
824
 
        mov     edx,edi                 ; Save edi
825
 
        mov     eax,esi                 ; Save esi
826
 
        mov     esi,P[esp]              ; get suffix
827
 
        mov     edi,P-SIZEPTR[esp]      ; s1
828
 
        push    eax                     ; push esi
829
 
        mov     eax,1                   ; Ok and zero-test
830
 
@@:     cmp     ah,[esi]
831
 
        jz      suf_ok                  ; End of string; found suffix
832
 
        cmpsb                           ; Compare strings
833
 
        jz      @B                      ; Same, possible prefix
834
 
        xor     eax,eax                 ; Not suffix
835
 
suf_ok: pop     esi
836
 
        mov     edi,edx
837
 
        ret
838
 
_is_prefix endp
839
 
        endcode _is_prefix
840
 
 
841
 
        ;
842
 
        ; Find a substring in string
843
 
        ; Arg: str,search
844
 
        ;
845
 
 
846
 
        begcode strstr
847
 
        public  _strstr
848
 
_strstr proc near
849
 
        push    ebp
850
 
        mov     ebp,esp
851
 
        fix_es  1
852
 
        push    EDI
853
 
        push    ESI
854
 
        mov     esi,P[ebp]              ; str
855
 
        mov     edi,P+SIZEPTR[ebp]      ; search
856
 
        mov     ecx,edi
857
 
        inc     ecx                     ; ECX = search+1
858
 
        mov     ah,[edi]                ; AH = First char in search
859
 
        jmps    sf_10
860
 
 
861
 
sf_00:  mov     esi,edx                 ; si = Current str-pos
862
 
sf_10:  mov     al,[esi]                ; Test if this char exist
863
 
        and     al,al
864
 
        jz      sf_90                   ; End of string, didn't find search
865
 
        inc     esi
866
 
        cmp     al,ah
867
 
        jnz     sf_10                   ; Didn't find first char, continue
868
 
        mov     edx,esi                 ; Save str-pos in EDX
869
 
        mov     edi,ecx
870
 
sf_20:  cmp     BYTE PTR [edi],0
871
 
        jz      sf_fo                   ; Found substring
872
 
        cmpsb
873
 
        jz      sf_20                   ; Char ok
874
 
        jmps    sf_00                   ; Next str-pos
875
 
 
876
 
sf_90:  mov     edx,1                   ; Return Null
877
 
sf_fo:  mov     eax,edx                 ; Char found here
878
 
        dec     eax                     ; Pointed one after
879
 
        pop     ESI
880
 
        pop     EDI
881
 
        pop     ebp
882
 
        ret
883
 
_strstr endp
884
 
        endcode strstr
885
 
 
886
 
        ;
887
 
        ; Make a string of len length from another string
888
 
        ; Arg: dst,src,length
889
 
        ; ret: end of dst
890
 
        ;
891
 
 
892
 
        begcode strmake
893
 
        public  _strmake
894
 
_strmake proc near
895
 
        push    ebp
896
 
        mov     ebp,esp
897
 
        fix_es  1
898
 
        push    EDI
899
 
        push    ESI
900
 
        mov     edi,P[ebp]              ; dst
901
 
        mov     esi,P+SIZEPTR[ebp]      ; src
902
 
        mov     ecx,P+SIZEPTR*2[ebp]    ; Length of memory-area
903
 
        clr     al                      ; For test of end-null
904
 
        jcxz    sm_90                   ; Nothing to move, put zero at end.
905
 
 
906
 
@@:     cmp     al,[esi]                ; Next char to move
907
 
        movsb                           ; move arg
908
 
        jz      sm_99                   ; last char, we are ready
909
 
        loop    @B                      ; Continue moving
910
 
sm_90:  mov     BYTE PTR [edi],al       ; Set end pos
911
 
        inc     edi                     ; Fix that di points at end null
912
 
sm_99:  dec     edi                     ; di points now at end null
913
 
        mov     eax,edi                 ; Ret value in DX:AX
914
 
        pop     ESI
915
 
        pop     EDI
916
 
        pop     ebp
917
 
        ret
918
 
_strmake        ENDP
919
 
        endcode strmake
920
 
 
921
 
        ;
922
 
        ; Find length of string with maxlength
923
 
        ; arg: str,maxlength
924
 
        ; ret: length
925
 
        ;
926
 
 
927
 
        begcode strnlen
928
 
        public  _strnlen
929
 
_strnlen proc near
930
 
        push    ebp
931
 
        mov     ebp,esp
932
 
        fix_es  1
933
 
        push    edi
934
 
        mov     edi,P[ebp]              ; Str
935
 
        mov     ecx,P+SIZEPTR[ebp]      ; length
936
 
        mov     edx,edi                 ; Save str to calc length
937
 
        jcxz    sn_10                   ; Length = 0
938
 
        clr     al                      ; Find end of string
939
 
        repne   scasb                   ; Find strend or length
940
 
        jnz     sn_10
941
 
        dec     edi                     ; DI points at last null
942
 
sn_10:  mov     eax,edi
943
 
        sub     eax,edx                 ; Ax = length
944
 
        pop     edi
945
 
        pop     ebp
946
 
        ret
947
 
_strnlen        ENDP
948
 
        endcode strnlen
949
 
 
950
 
        ;
951
 
        ; Move a string with max len chars
952
 
        ; arg: dst,src,len
953
 
        ; ret: pos to first null or dst+len
954
 
 
955
 
        begcode strnmov
956
 
        public  _strnmov
957
 
_strnmov PROC near
958
 
        push    ebp
959
 
        mov     ebp,esp
960
 
        fix_es  1
961
 
        push    EDI
962
 
        push    ESI
963
 
        mov     edi,P[ebp]              ; dst
964
 
        mov     esi,P+SIZEPTR[ebp]      ; src
965
 
        mov     ecx,P+(SIZEPTR*2)[ebp]  ; length
966
 
        jcxz    snm_99                  ; Nothing to do
967
 
        clr     al                      ; For test of end-null
968
 
 
969
 
@@:     cmp     al,[esi]                ; Next char to move
970
 
        movsb                           ; move arg
971
 
        jz      snm_20                  ; last char, fill with null
972
 
        loop    @B                      ; Continue moving
973
 
        inc     edi                     ; Point two after last
974
 
snm_20: dec     edi                     ; Point at first null (or last+1)
975
 
snm_99: mov     eax,edi                 ; Pointer at last char
976
 
        pop     ESI
977
 
        pop     EDI
978
 
        pop     ebp
979
 
        ret
980
 
_strnmov        ENDP
981
 
        endcode strnmov
982
 
 
983
 
;
984
 
; Zortech has this one in standard library
985
 
;
986
 
 
987
 
        begcode strmov
988
 
        public  _strmov
989
 
_strmov proc    near
990
 
        mov     ecx,esi                 ; Save old esi and edi
991
 
        mov     edx,edi
992
 
        mov     esi,P[esp]              ; get source pointer (s2)
993
 
        mov     edi,P-SIZEPTR[esp]      ; EDI -> s1
994
 
        fix_es  1
995
 
@@:     mov     al,[esi]
996
 
        movsb                           ; move arg
997
 
        and     al,al
998
 
        jnz     @B                      ; Not last
999
 
        mov     eax,edi
1000
 
        dec     eax
1001
 
        mov     esi,ecx                 ; Restore args
1002
 
        mov     edi,edx
1003
 
        ret
1004
 
_strmov endp
1005
 
        endcode strmov
1006
 
 
1007
 
endif ; M_I386
1008
 
 
1009
 
        END