All pastes #413586 Raw Edit

PEACEY

public text v1 · immutable
#413586 ·published 2007-03-28 15:23 UTC
rendered paste body
; 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