~stewart/drizzle/embedded-innodb-create-select-transaction-arrgh

« back to all changes in this revision

Viewing changes to strings/strings.asm

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

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