Add memory utilities and math utils

This commit adds the well known primitive memory functions:

- Copy Memory
- Compare Memory for being equal
- Set Memory to a value

It also adds a math utility file at the according location.
This commit is contained in:
Eric-Paul Ickhorn 2024-06-16 23:04:29 +02:00
parent c3f2c7fbfc
commit d773a8f9e2
Signed by: epickh
GPG Key ID: 1358818BAA38B104
2 changed files with 204 additions and 0 deletions

View File

@ -0,0 +1,52 @@
; Arguments:
; [Furthest from EBP]
; 1. U32 Stepping
; 0. U32 Affected Value
; [Nearest to EBP]
;
; Returns:
; - EAX: The next higher multiple of the stepping,
; as calculated from affected value.
ceil_to:
.prolog:
push esi
sub esp, 16
mov esi, esp
mov [esi + (16 - 4)], ecx
mov [esi + (16 - 8)], edx
.check_values:
mov eax, [ebp - 4]
cmp eax, 0
jne .affected_value_is_valid
xor eax, eax
jmp .epilog
.affected_value_is_valid:
mov ecx, [ebp - 8]
cmp ecx, 0
jne .calculate
xor eax, eax
jmp .epilog
.calculate:
; Calculate how much needs ot be added to the
; affected value for it to become a multiple of
; the stepping using the remainder part of the division.
div ecx
; EDX now contains how much the affected value
; 'goes over' the last multiple of the stepping.
; Now, it can be calculated how much has to be added
; to the affected value to make it the next multiple
; of the stepping.
mov ecx, [ebp - 8]
sub ecx, edx
mov eax, [ebp - 4]
add eax, ecx
.epilog:
mov edx, [esi + (16 - 8)]
mov ecx, [esi + (16 - 4)]
add esp, 16
pop esi
ret

View File

@ -0,0 +1,152 @@
mem_copy:
; todo(perf): Copy multiple bytes at once
.prolog:
push esi
sub esp, 64
mov esi, esp
; Save registers
mov [esi + (64 - 4)], eax
mov [esi + (64 - 8)], ebx
mov [esi + (64 - 12)], ecx
mov [esi + (64 - 16)], edx
mov [esi + (64 - 20)], edi
.body:
mov edx, [ebp - 4] ; Destination
mov edi, [ebp - 8] ; Source
xor eax, eax ; Current Byte Offset
.body.copy_loop:
mov ebx, edi
add ebx, eax
mov cl, [ebx]
mov ebx, edx
add ebx, eax
mov [ebx], cl
inc eax
cmp eax, [ebp - 12]
jb .body.copy_loop
.epilog:
; Restore registers
mov eax, [esi + (64 - 4)]
mov ebx, [esi + (64 - 8)]
mov ecx, [esi + (64 - 12)]
mov edx, [esi + (64 - 16)]
mov edi, [esi + (64 - 20)]
add esp, 64
pop esi
ret
; Furthest from EBP
; 3. Length of block 1 and block 2
; 2. Block 2
; 1. Block 1
; Nearest to EBP
mem_equal:
.prolog:
push esi
sub esp, 32
mov esi, esp
; Save registers
mov [esi + (32 - 4)], ebx
mov [esi + (32 - 8)], ecx
mov [esi + (32 - 12)], edx
mov [esi + (32 - 16)], edi
.body:
mov edx, [ebp - 4] ; Block 1
mov edi, [ebp - 8] ; Block 2
xor eax, eax ; Current Byte Offset
.body.compare_loop:
mov ebx, edx
add ebx, eax
mov dl, [ebx]
mov ebx, edi
add ebx, eax
mov dh, [ebx]
inc eax
cmp dl, dh
je .body.compare_loop.condition
; On NOT equal
xor eax, eax
jmp .epilog
.body.compare_loop.condition:
inc eax
cmp eax, [ebp - 12]
jb .body.compare_loop
mov eax, 1
.epilog:
; Restore registers
mov ebx, [esi + (32 - 4)]
mov ecx, [esi + (32 - 8)]
mov edx, [esi + (32 - 12)]
mov edi, [esi + (32 - 16)]
add esp, 32
pop esi
ret
; ebp - 4: Area Pointer
; ebp - 8: Length of Area
; ebp - 12: Byte Value to set
mem_set:
.prolog:
push esi
sub esp, 64
mov esi, esp
; Save registers
mov [esi + (64 - 4)], eax
mov [esi + (64 - 8)], ebx
mov [esi + (64 - 12)], ecx
mov [esi + (64 - 16)], edx
mov [esi + (64 - 20)], edi
.body:
mov ebx, [ebp - 4]
mov dl, [ebp - 12]
; Make EDI the Last Byte Pointer
mov edi, [ebp - 4]
add edi, [ebp - 8]
.body.setter_loop:
cmp ebx, edi
jae .epilog
mov [ebx], dl
inc ebx
jb .body.setter_loop
.epilog:
; Restore registers
mov eax, [esi + (64 - 4)]
mov ebx, [esi + (64 - 8)]
mov ecx, [esi + (64 - 12)]
mov edx, [esi + (64 - 16)]
mov edi, [esi + (64 - 20)]
add esp, 64
pop esi
ret