; memory.asm ; Methods for string manipulation ; Can be used in C global _asm_copy, _asm_find, _asm_strlen, _asm_strcpy segment .text ; Function _asm_copy ; C prototype: ; void asm_copy( void *dest, const void *src, unsigned sz ); ; Parameters: ; dest -> pointer to the string buffer to copy to ; src -> pointer to the string buffer to copy from ; sz -> number of bytes to copy %define dest [ebp + 8] %define src [ebp + 12] %define sz [ebp + 16] _asm_copy: enter 0, 0 push esi ; Push these two push edi ; They might be modified! mov esi, src ; esi = from mov edi, dest ; edi = to mov ecx, sz ; ecx = # of bytes to copy cld ; Clear the direction flag ( Positive ) rep movsb ; Execute movsb ECX times pop edi pop esi leave ret ; Function _asm_find ; Searches memory for a given byte ; void *asm_find( const void *src, char target, unsigned sz ) ; Parameters: ; src -> pointer to buffer to search in ; target -> byte value to search for ; sz -> Number of bytes in buffer ( src ) ; ; Return Value: ; Pointer to first occurence of target in buffer is found ; Else, NULL is returned. ; NOTE: target is a BYTE value, but is pushed on stack as a DWORD value. ; The byte value is stored in the lower 8-bits %define src [ebp + 8] %define target [ebp + 12] %define sz [ebp + 16] _asm_find: enter 0, 0 push edi mov eax, target ; al has the value to search for - Because it is one byte mov edi, src mov ecx, sz cld repne scasb ; scan until ECX == 0 or [ES:EDI] == AL je found ; If ZF is set, then found value mov eax, 0 ; If not found, return a NULL pointer jmp short quit ; Jump to quit if not found found: mov eax, edi dec eax ; Because the found is in (DI - 1) NOT DI quit: pop edi leave ret ; function _asm_strlen ; Returns the size of a string ; C prototype: ; usigned asm_strlen( const char * ); ; Parameter(s): ; src -> pointer to the string ; ; Return Value: ; Number of characters in the string provided ; Not counting ending termination character. ( In EAX ) %define src [ebp + 8] _asm_strlen: enter 0, 0 push edi mov edi, src ; edi = pointer to source string mov ecx, 0FFFFFFFFh ; Largest possible ECX xor al, al ; al = 0 == EAX = 0 but stored in the lower 8 bits ( al ) cld repnz scasb ; Scan for terminating NULL character '\0' ; because repnz will add one after finding the NULL character, ; the length is at (FFFFFFFF-1) - ECX == FFFFFFFE = ECX mov eax, 0FFFFFFFEh sub eax, ecx ; eax = eax - ecx == 4 294 967 294 - decremented ecx value after strng find pop edi leave ret ; Function _asm_strcpy ; C Prototype: ; void asm_strcpy( char *dest, const char *src ); ; Parameters ; dest -> pointer to the string to copy to ; src -> pointer to the string to copy from ; %define dest [ebp + 8] %define src [ebp + 12] _asm_strcpy: enter 0, 0 push esi ; Again save these two push edi ; ... mov edi, dest ; edi = dest string mov esi, src ; esi = src string cld ; clear the direction flag cpy_loop: lodsb ; Load AL and increment si stosb ; Store AL and increment di or al, al ; al = 0 Set the condition flag jnz cpy_loop ; While we havnt passed the '\0' character, continue pop edi pop esi leave ret ; End .text segment