~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
 
        ; Find a substring in string, return index
481
 
        ; Arg: str,search
482
 
        ;
483
 
 
484
 
        PUBLIC  _strinstr
485
 
_strinstr       PROC
486
 
        push    bp
487
 
        mov     bp,sp
488
 
        push    di
489
 
        les     di,DWORD PTR [bp+10]    ; search
490
 
        push    es
491
 
        push    di
492
 
        les     di,DWORD PTR [bp+6]     ; str
493
 
        push    es
494
 
        push    di
495
 
        call    _strstr
496
 
        mov     cx,ax
497
 
        or      cx,dx
498
 
        jz      si_99
499
 
        sub     ax,di                   ; Pos from start
500
 
        inc     ax                      ; And first pos = 1
501
 
si_99:  add     sp,8
502
 
        pop     di
503
 
        pop     bp
504
 
        ret
505
 
_strinstr       ENDP
506
 
 
507
 
        ;
508
 
        ; Make a string of len length from another string
509
 
        ; Arg: dst,src,length
510
 
        ; ret: end of dst
511
 
        ;
512
 
 
513
 
        PUBLIC  _strmake
514
 
_strmake        PROC
515
 
        mov     bx,bp
516
 
        mov     bp,sp
517
 
        push    ds
518
 
        push    di
519
 
        push    si
520
 
        les     di,DWORD PTR [bp+4]     ; dst
521
 
        lds     si,DWORD PTR [bp+8]     ; src
522
 
        mov     cx,WORD PTR [bp+12]     ; Length of memory-area
523
 
        xor     al,al                   ; For test of end-null
524
 
        jcxz    sm_90                   ; Nothing to move, put zero at end.
525
 
;       cld                             ; Work uppward
526
 
 
527
 
@@:     cmp     al,ds:[si]              ; Next char to move
528
 
        movsb                           ; move arg
529
 
        jz      sm_99                   ; last char, we are ready
530
 
        loop    @B                      ; Continue moving
531
 
sm_90:  mov     BYTE PTR es:[di],al     ; Set end pos
532
 
        inc     di                      ; Fix that di points at end null
533
 
sm_99:  dec     di                      ; di points now at end null
534
 
        mov     ax,di                   ; Ret value in DX:AX
535
 
        mov     dx,es
536
 
        pop     si
537
 
        pop     di
538
 
        pop     ds
539
 
        mov     bp,bx
540
 
        ret
541
 
_strmake        ENDP
542
 
 
543
 
        ;
544
 
        ; Find length of string with maxlength
545
 
        ; arg: str,maxlength
546
 
        ; ret: length
547
 
        ;
548
 
 
549
 
        PUBLIC  _strnlen
550
 
_strnlen        PROC
551
 
        mov     bx,bp
552
 
        mov     bp,sp
553
 
        push    di
554
 
        les     di,DWORD PTR [bp+4]     ; Str
555
 
        mov     cx,WORD PTR [bp+8]      ; length
556
 
        mov     dx,di                   ; Save str to calc length
557
 
        jcxz    sn_10                   ; Length = 0
558
 
        xor     al,al                   ; Find end of string
559
 
;       cld
560
 
        repne   scasb                   ; Find strend or length
561
 
        jnz     sn_10
562
 
        dec     di                      ; DI points at last null
563
 
sn_10:  mov     ax,di
564
 
        sub     ax,dx                   ; Ax = length
565
 
        pop     di
566
 
        mov     bp,bx
567
 
        ret
568
 
_strnlen        ENDP
569
 
 
570
 
        ;
571
 
        ; Move a string with max len chars
572
 
        ; arg: dst,src,len
573
 
        ; ret: pos to first null or dst+len
574
 
 
575
 
        PUBLIC  _strnmov
576
 
_strnmov        PROC
577
 
        mov     bx,bp
578
 
        mov     bp,sp
579
 
        push    ds
580
 
        push    di
581
 
        push    si
582
 
        les     di,DWORD PTR [bp+4]     ; dst
583
 
        lds     si,DWORD PTR [bp+8]     ; src
584
 
        mov     cx,WORD PTR [bp+12]     ; length
585
 
        jcxz    snm_99                  ; Nothing to do
586
 
        xor     al,al                   ; For test of end-null
587
 
;       cld
588
 
 
589
 
@@:     cmp     al,ds:[si]              ; Next char to move
590
 
        movsb                           ; move arg
591
 
        jz      snm_20                  ; last char, fill with null
592
 
        loop    @B                      ; Continue moving
593
 
        inc     di                      ; Point two after last
594
 
snm_20: dec     di                      ; Point at first null (or last+1)
595
 
snm_99: mov     ax,di                   ; Pointer at last char
596
 
        mov     dx,es                   ; To-segment
597
 
        pop     si
598
 
        pop     di
599
 
        pop     ds
600
 
        mov     bp,bx                   ; Restore
601
 
        ret
602
 
_strnmov        ENDP
603
 
 
604
 
else    ; M_I386
605
 
 
606
 
include macros.asm
607
 
 
608
 
q_stos  MACRO                           ; as rep stosb but quicker, Uses edx
609
 
        mov     ah,al                   ;(2) Set up a 32 bit pattern.
610
 
        mov     edx,eax                 ;(2)
611
 
        shl     edx,16                  ;(3)
612
 
        or      eax,edx                 ;(2) EAX has the 32 bit pattern.
613
 
 
614
 
        mov     edx,ecx                 ;(2) Save the count of bytes.
615
 
        shr     ecx,2                   ;(2) Number of dwords.
616
 
        rep     stosd                   ;(5 + 5n)
617
 
        mov     cl,3                    ;(2)
618
 
        and     ecx,edx                 ;(2) Fill in the remaining odd bytes.
619
 
        rep     stosb                   ; Move last bytes if any
620
 
        ENDM
621
 
 
622
 
fix_es  MACRO   fix_cld                 ; Load ES if neaded
623
 
  ife ESeqDS
624
 
        mov     ax,ds
625
 
        mov     es,ax
626
 
  endif
627
 
  ifnb <fix_cld>
628
 
        cld
629
 
  endif
630
 
        ENDM
631
 
 
632
 
        ;
633
 
        ; Move a memory area
634
 
        ; Args: to,from,length
635
 
        ; Acts as one byte was moved a-time from dst to source.
636
 
        ;
637
 
 
638
 
        begcode bmove
639
 
        public  _bmove
640
 
_bmove  proc near
641
 
        fix_es  1
642
 
        mov     edx,edi
643
 
        mov     eax,esi
644
 
        mov     edi,P-SIZEPTR[esp]      ;p1
645
 
        mov     esi,P[esp]              ;p2
646
 
        mov     ecx,P+SIZEPTR[esp]
647
 
        rep     movsb                   ; Not q_movs because overlap ?
648
 
        mov     esi,eax
649
 
        mov     edi,edx
650
 
        ret
651
 
_bmove  ENDP
652
 
        endcode bmove
653
 
 
654
 
        ;
655
 
        ; Move a alligned, not overlapped, by (long) divided memory area
656
 
        ; Args: to,from,length
657
 
        ;
658
 
 
659
 
        begcode bmove_align
660
 
        public  _bmove_align
661
 
_bmove_align    proc near
662
 
        fix_es  1
663
 
        mov     edx,edi
664
 
        mov     eax,esi
665
 
        mov     edi,P-SIZEPTR[esp]      ;to
666
 
        mov     esi,P[esp]              ;from
667
 
        mov     ecx,P+SIZEPTR[esp]      ;length
668
 
        add     cx,3                    ;fix if not divisible with long
669
 
        shr     cx,2
670
 
        rep     movsd
671
 
        mov     esi,eax
672
 
        mov     edi,edx
673
 
        ret
674
 
_bmove_align    ENDP
675
 
        endcode bmove_align
676
 
 
677
 
        ;
678
 
        ; Move a string from higher to lower
679
 
        ; Arg from+1,to+1,length
680
 
        ;
681
 
 
682
 
        begcode bmove_upp
683
 
        public  _bmove_upp
684
 
_bmove_upp      proc near
685
 
        fix_es
686
 
        std                             ; Work downward
687
 
        mov     edx,edi
688
 
        mov     eax,esi
689
 
        mov     edi,P-SIZEPTR[esp]      ;p1
690
 
        mov     esi,P[esp]              ;p2
691
 
        mov     ecx,P+SIZEPTR[esp]
692
 
        dec     edi                     ; Don't move last arg
693
 
        dec     esi
694
 
        rep     movsb                   ; One byte a time because overlap !
695
 
        cld                             ; C compilator wants cld
696
 
        mov     esi,eax
697
 
        mov     edi,edx
698
 
        ret
699
 
_bmove_upp ENDP
700
 
        endcode bmove_upp
701
 
 
702
 
        ;
703
 
        ; Append fillchars to string
704
 
        ; Args: dest,len,fill
705
 
        ;
706
 
 
707
 
        begcode strappend
708
 
        public  _strappend
709
 
_strappend      proc near
710
 
        push    ebp
711
 
        mov     ebp,esp
712
 
        fix_es  1
713
 
        push    edi
714
 
        mov     edi,P[ebp]              ; Memory pointer
715
 
        mov     ecx,P+SIZEPTR[ebp]      ; Length
716
 
        clr     eax                     ; Find end of string
717
 
        repne   scasb
718
 
        jnz     sa_99                   ; String to long, shorten it
719
 
        movzx   eax,byte ptr P+(2*SIZEPTR)[ebp] ; Fillchar
720
 
        dec     edi                     ; Point at end null
721
 
        inc     ecx                     ; rep made one dec for null-char
722
 
        q_stos                          ; Store al in string
723
 
sa_99:  mov     BYTE PTR [edi],0        ; End of string
724
 
        pop     edi
725
 
        pop     ebp
726
 
        ret
727
 
_strappend      ENDP
728
 
        endcode strappend
729
 
 
730
 
        ;
731
 
        ; Find if string contains any char in another string
732
 
        ; Arg: str,set
733
 
        ; Ret: Pointer to first found char in str
734
 
        ;
735
 
 
736
 
        begcode strcont
737
 
        PUBLIC  _strcont
738
 
_strcont proc near
739
 
        push    ebp
740
 
        mov     ebp,esp
741
 
        fix_es  1
742
 
        mov     edx,edi
743
 
        push    esi
744
 
        mov     esi,P[ebp]              ; str
745
 
        mov     ecx,P+SIZEPTR[ebp]      ; Set
746
 
        clr     ah                      ; For endtest
747
 
        jmps    sc_60
748
 
 
749
 
sc_10:  scasb
750
 
        jz      sc_fo                   ; Found char
751
 
sc_20:  cmp     ah,[edi]                ; Test if null
752
 
        jnz     sc_10                   ; Not end of set yet
753
 
        inc     esi                     ; Next char in str
754
 
sc_60:  mov     edi,ecx                 ; edi = Set
755
 
        mov     al,[esi]                ; Test if this char exist
756
 
        and     al,al
757
 
        jnz     sc_20                   ; Not end of string
758
 
        clr     esi                     ; Return Null
759
 
sc_fo:  mov     eax,esi                 ; Char found here
760
 
        mov     edi,edx                 ; Restore
761
 
        pop     esi
762
 
        pop     ebp
763
 
        ret
764
 
_strcont        ENDP
765
 
        endcode strcont
766
 
 
767
 
        ;
768
 
        ; Found end of string
769
 
        ; Arg: str
770
 
        ; ret: Pointer to end null
771
 
        ;
772
 
 
773
 
        begcode strend
774
 
        public  _strend
775
 
_strend proc near
776
 
        fix_es  1
777
 
        mov     edx,edi                 ; Save
778
 
        mov     edi,P-SIZEPTR[esp]      ; str
779
 
        clr     eax                     ; Find end of string
780
 
        mov     ecx,eax
781
 
        dec     ecx                     ; ECX = -1
782
 
        repne   scasb
783
 
        mov     eax,edi
784
 
        dec     eax
785
 
        mov     edi,edx                 ; Restore
786
 
        ret
787
 
_strend endp
788
 
        endcode strend
789
 
 
790
 
        ;
791
 
        ; Make a string with len fill-chars and endnull
792
 
        ; Args: dest,len,fill
793
 
        ; Ret:  dest+len
794
 
        ;
795
 
 
796
 
        begcode strfill
797
 
        public  _strfill
798
 
_strfill proc near
799
 
        push    ebp
800
 
        mov     ebp,esp
801
 
        fix_es  1
802
 
        push    edi
803
 
        mov     edi,P[ebp]              ; Memory pointer
804
 
        mov     ecx,P+SIZEPTR[ebp]      ; Length
805
 
        movzx   eax,byte ptr P+(2*SIZEPTR)[ebp] ; Fill
806
 
        q_stos
807
 
        mov     BYTE PTR [edi],0        ; End NULL
808
 
        mov     eax,edi                 ; End i DX:AX
809
 
        pop     edi
810
 
        pop     ebp
811
 
        ret
812
 
_strfill endp
813
 
        endcode strfill
814
 
 
815
 
        ;
816
 
        ; Find a char in or end of a string
817
 
        ; Arg: str,char
818
 
        ; Ret: pointer to found char or NullS
819
 
        ;
820
 
 
821
 
        begcode strcend
822
 
        public  _strcend
823
 
_strcend proc near
824
 
        push    ebp
825
 
        mov     ebp,esp
826
 
        fix_es  1
827
 
        mov     edx,edi
828
 
        mov     edi,P[ebp]              ; str
829
 
        mov     ah,P+SIZEPTR[ebp]       ; search
830
 
        clr     al                      ; for scasb to find end
831
 
 
832
 
@@:     cmp     ah,[edi]
833
 
        jz      @F                      ; Found char
834
 
        scasb
835
 
        jnz     @B                      ; Not end
836
 
        dec     edi                     ; Not found, point at end of string
837
 
@@:     mov     eax,edi
838
 
        mov     edi,edx                 ; Restore
839
 
        pop     ebp
840
 
        ret
841
 
_strcend        ENDP
842
 
        endcode strcend
843
 
 
844
 
        ;
845
 
        ; Test if string has a given suffix
846
 
        ;
847
 
 
848
 
        begcode is_prefix
849
 
        public  _is_prefix
850
 
_is_prefix proc near
851
 
        fix_es  1
852
 
        mov     edx,edi                 ; Save edi
853
 
        mov     eax,esi                 ; Save esi
854
 
        mov     esi,P[esp]              ; get suffix
855
 
        mov     edi,P-SIZEPTR[esp]      ; s1
856
 
        push    eax                     ; push esi
857
 
        mov     eax,1                   ; Ok and zero-test
858
 
@@:     cmp     ah,[esi]
859
 
        jz      suf_ok                  ; End of string; found suffix
860
 
        cmpsb                           ; Compare strings
861
 
        jz      @B                      ; Same, possible prefix
862
 
        xor     eax,eax                 ; Not suffix
863
 
suf_ok: pop     esi
864
 
        mov     edi,edx
865
 
        ret
866
 
_is_prefix endp
867
 
        endcode _is_prefix
868
 
 
869
 
        ;
870
 
        ; Find a substring in string
871
 
        ; Arg: str,search
872
 
        ;
873
 
 
874
 
        begcode strstr
875
 
        public  _strstr
876
 
_strstr proc near
877
 
        push    ebp
878
 
        mov     ebp,esp
879
 
        fix_es  1
880
 
        push    EDI
881
 
        push    ESI
882
 
        mov     esi,P[ebp]              ; str
883
 
        mov     edi,P+SIZEPTR[ebp]      ; search
884
 
        mov     ecx,edi
885
 
        inc     ecx                     ; ECX = search+1
886
 
        mov     ah,[edi]                ; AH = First char in search
887
 
        jmps    sf_10
888
 
 
889
 
sf_00:  mov     esi,edx                 ; si = Current str-pos
890
 
sf_10:  mov     al,[esi]                ; Test if this char exist
891
 
        and     al,al
892
 
        jz      sf_90                   ; End of string, didn't find search
893
 
        inc     esi
894
 
        cmp     al,ah
895
 
        jnz     sf_10                   ; Didn't find first char, continue
896
 
        mov     edx,esi                 ; Save str-pos in EDX
897
 
        mov     edi,ecx
898
 
sf_20:  cmp     BYTE PTR [edi],0
899
 
        jz      sf_fo                   ; Found substring
900
 
        cmpsb
901
 
        jz      sf_20                   ; Char ok
902
 
        jmps    sf_00                   ; Next str-pos
903
 
 
904
 
sf_90:  mov     edx,1                   ; Return Null
905
 
sf_fo:  mov     eax,edx                 ; Char found here
906
 
        dec     eax                     ; Pointed one after
907
 
        pop     ESI
908
 
        pop     EDI
909
 
        pop     ebp
910
 
        ret
911
 
_strstr endp
912
 
        endcode strstr
913
 
 
914
 
        ;
915
 
        ; Find a substring in string, return index
916
 
        ; Arg: str,search
917
 
        ;
918
 
 
919
 
        begcode strinstr
920
 
        public  _strinstr
921
 
_strinstr proc near
922
 
        push    ebp
923
 
        mov     ebp,esp
924
 
        push    P+SIZEPTR[ebp]          ; search
925
 
        push    P[ebp]                  ; str
926
 
        call    _strstr
927
 
        add     esp,SIZEPTR*2
928
 
        or      eax,eax
929
 
        jz      si_99                   ; Not found, return NULL
930
 
        sub     eax,P[ebp]              ; Pos from start
931
 
        inc     eax                     ; And first pos = 1
932
 
si_99:  pop     ebp
933
 
        ret
934
 
_strinstr       endp
935
 
        endcode strinstr
936
 
 
937
 
        ;
938
 
        ; Make a string of len length from another string
939
 
        ; Arg: dst,src,length
940
 
        ; ret: end of dst
941
 
        ;
942
 
 
943
 
        begcode strmake
944
 
        public  _strmake
945
 
_strmake proc near
946
 
        push    ebp
947
 
        mov     ebp,esp
948
 
        fix_es  1
949
 
        push    EDI
950
 
        push    ESI
951
 
        mov     edi,P[ebp]              ; dst
952
 
        mov     esi,P+SIZEPTR[ebp]      ; src
953
 
        mov     ecx,P+SIZEPTR*2[ebp]    ; Length of memory-area
954
 
        clr     al                      ; For test of end-null
955
 
        jcxz    sm_90                   ; Nothing to move, put zero at end.
956
 
 
957
 
@@:     cmp     al,[esi]                ; Next char to move
958
 
        movsb                           ; move arg
959
 
        jz      sm_99                   ; last char, we are ready
960
 
        loop    @B                      ; Continue moving
961
 
sm_90:  mov     BYTE PTR [edi],al       ; Set end pos
962
 
        inc     edi                     ; Fix that di points at end null
963
 
sm_99:  dec     edi                     ; di points now at end null
964
 
        mov     eax,edi                 ; Ret value in DX:AX
965
 
        pop     ESI
966
 
        pop     EDI
967
 
        pop     ebp
968
 
        ret
969
 
_strmake        ENDP
970
 
        endcode strmake
971
 
 
972
 
        ;
973
 
        ; Find length of string with maxlength
974
 
        ; arg: str,maxlength
975
 
        ; ret: length
976
 
        ;
977
 
 
978
 
        begcode strnlen
979
 
        public  _strnlen
980
 
_strnlen proc near
981
 
        push    ebp
982
 
        mov     ebp,esp
983
 
        fix_es  1
984
 
        push    edi
985
 
        mov     edi,P[ebp]              ; Str
986
 
        mov     ecx,P+SIZEPTR[ebp]      ; length
987
 
        mov     edx,edi                 ; Save str to calc length
988
 
        jcxz    sn_10                   ; Length = 0
989
 
        clr     al                      ; Find end of string
990
 
        repne   scasb                   ; Find strend or length
991
 
        jnz     sn_10
992
 
        dec     edi                     ; DI points at last null
993
 
sn_10:  mov     eax,edi
994
 
        sub     eax,edx                 ; Ax = length
995
 
        pop     edi
996
 
        pop     ebp
997
 
        ret
998
 
_strnlen        ENDP
999
 
        endcode strnlen
1000
 
 
1001
 
        ;
1002
 
        ; Move a string with max len chars
1003
 
        ; arg: dst,src,len
1004
 
        ; ret: pos to first null or dst+len
1005
 
 
1006
 
        begcode strnmov
1007
 
        public  _strnmov
1008
 
_strnmov PROC near
1009
 
        push    ebp
1010
 
        mov     ebp,esp
1011
 
        fix_es  1
1012
 
        push    EDI
1013
 
        push    ESI
1014
 
        mov     edi,P[ebp]              ; dst
1015
 
        mov     esi,P+SIZEPTR[ebp]      ; src
1016
 
        mov     ecx,P+(SIZEPTR*2)[ebp]  ; length
1017
 
        jcxz    snm_99                  ; Nothing to do
1018
 
        clr     al                      ; For test of end-null
1019
 
 
1020
 
@@:     cmp     al,[esi]                ; Next char to move
1021
 
        movsb                           ; move arg
1022
 
        jz      snm_20                  ; last char, fill with null
1023
 
        loop    @B                      ; Continue moving
1024
 
        inc     edi                     ; Point two after last
1025
 
snm_20: dec     edi                     ; Point at first null (or last+1)
1026
 
snm_99: mov     eax,edi                 ; Pointer at last char
1027
 
        pop     ESI
1028
 
        pop     EDI
1029
 
        pop     ebp
1030
 
        ret
1031
 
_strnmov        ENDP
1032
 
        endcode strnmov
1033
 
 
1034
 
;
1035
 
; Zortech has this one in standard library
1036
 
;
1037
 
 
1038
 
        begcode strmov
1039
 
        public  _strmov
1040
 
_strmov proc    near
1041
 
        mov     ecx,esi                 ; Save old esi and edi
1042
 
        mov     edx,edi
1043
 
        mov     esi,P[esp]              ; get source pointer (s2)
1044
 
        mov     edi,P-SIZEPTR[esp]      ; EDI -> s1
1045
 
        fix_es  1
1046
 
@@:     mov     al,[esi]
1047
 
        movsb                           ; move arg
1048
 
        and     al,al
1049
 
        jnz     @B                      ; Not last
1050
 
        mov     eax,edi
1051
 
        dec     eax
1052
 
        mov     esi,ecx                 ; Restore args
1053
 
        mov     edi,edx
1054
 
        ret
1055
 
_strmov endp
1056
 
        endcode strmov
1057
 
 
1058
 
endif ; M_I386
1059
 
 
1060
 
        END