; 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