1 page ,132 2 title memccpy - copy bytes until character found 3;*** 4;memccpy.asm - copy bytes until a character is found 5; 6; Copyright (c) Microsoft Corporation. All rights reserved. 7; 8;Purpose: 9; defines _memccpy() - copies bytes until a specifed character 10; is found, or a maximum number of characters have been copied. 11; 12;******************************************************************************* 13 14 .xlist 15 include cruntime.inc 16 .list 17 18page 19;*** 20;char *_memccpy(dest, src, _c, count) - copy bytes until character found 21; 22;Purpose: 23; Copies bytes from src to dest until count bytes have been 24; copied, or up to and including the character _c, whichever 25; comes first. 26; 27; Algorithm: 28; char * 29; _memccpy (dest, src, _c, count) 30; char *dest, *src, _c; 31; unsigned int count; 32; { 33; while (count && (*dest++ = *src++) != _c) 34; count--; 35; 36; return(count ? dest : NULL); 37; } 38; 39;Entry: 40; char *dest - pointer to memory to receive copy 41; char *src - source of bytes 42; char _c - character to stop copy at 43; int count - max number of bytes to copy 44; 45;Exit: 46; returns pointer to byte immediately after _c in dest; 47; returns NULL if _c was never found 48; 49;Uses: 50; 51;Exceptions: 52; 53;******************************************************************************* 54 55 CODESEG 56 57 public _memccpy 58_memccpy proc \ 59 dest:ptr byte, \ 60 src:ptr byte, \ 61 _c:byte, \ 62 count:DWORD 63 64 OPTION PROLOGUE:NONE, EPILOGUE:NONE 65 66 .FPO ( 0, 4, 0, 0, 0, 0 ) 67 68 mov ecx,[esp + 10h] ; ecx = max byte count 69 push ebx ; save ebx 70 71 test ecx,ecx ; if it's nothing to move 72 jz ret_zero_len ; restore ebx, and return NULL 73 74 mov bh,[esp + 10h] ; bh = byte to look for 75 push esi ; save esi 76 77 test ecx,1 ; test if counter is odd or even 78 79 mov eax,[esp + 0ch] ; eax = dest , don't affect flags 80 mov esi,[esp + 10h] ; esi = source , don't affect flags 81 82; nop 83 jz lupe2 ; if counter is even, do double loop 84 ; else do one iteration, and drop into double loop 85 mov bl,[esi] ; get first byte into bl 86 add esi,1 ; kick src (esi points to src) 87 88 mov [eax],bl ; store it in dest 89 add eax,1 ; kick dest 90 91 cmp bl,bh ; see if we just moved the byte 92 je short toend 93 94 sub ecx,1 ; decrement counter 95 jz retnull ; drop into double loop if nonzero 96 97lupe2: 98 mov bl,[esi] ; get first byte into bl 99 add esi,2 ; kick esi (src) 100 101 cmp bl,bh ; check if we just moved the byte (from bl) 102 je toend_mov_inc ; store bl & exit 103 104 mov [eax],bl ; store first byte from bl 105 mov bl,[esi - 1] ; get second byte into bl 106 107 mov [eax + 1],bl ; store second byte from bl 108 add eax,2 ; kick eax (dest) 109 110 cmp bl,bh ; see if we just moved the byte 111 je short toend ; end of string 112 113 sub ecx,2 ; modify counter, and if nonzero continue 114 jnz lupe2 ; else drop out & return NULL 115 116retnull: 117 pop esi 118ret_zero_len: 119 xor eax,eax ; null pointer 120 pop ebx 121 122 ret ; _cdecl return 123 124toend_mov_inc: 125 mov [eax],bl ; store first byte from bl 126 add eax,1 ; eax points right after the value 127 128toend: pop esi 129 pop ebx 130 131 ret ; _cdecl return 132 133_memccpy endp 134 135 end 136