diff --git a/i386/loader/src-asm/utility/math.asm b/i386/loader/src-asm/utility/math.asm new file mode 100755 index 0000000..7ecf0ae --- /dev/null +++ b/i386/loader/src-asm/utility/math.asm @@ -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 diff --git a/i386/loader/src-asm/utility/memory.asm b/i386/loader/src-asm/utility/memory.asm new file mode 100755 index 0000000..b3c03c3 --- /dev/null +++ b/i386/loader/src-asm/utility/memory.asm @@ -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 +