From f3a8b2626aa5d541dfaf9c63a911e1893c0f4ba9 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Thu, 1 May 2025 01:32:45 +0200 Subject: Add semicolons separating the statements --- boot/common-boot.s | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 120 insertions(+), 2 deletions(-) (limited to 'boot/common-boot.s') diff --git a/boot/common-boot.s b/boot/common-boot.s index e5796f1..0cf31f1 100644 --- a/boot/common-boot.s +++ b/boot/common-boot.s @@ -1,6 +1,6 @@ .global _is_alpha, _is_digit, _is_alnum, _is_upper, _is_lower .global _write_out, _read_file, _write_error, _put_char, _printi -.global _get, _memcmp +.global _get, _memcmp, _memchr, _memmem, _memcpy .global _divide_by_zero_error, _exit .section .rodata @@ -16,7 +16,8 @@ new_line: .ascii "\n" .section .text -# Write the current token to stderr. +# Write the current token to stderr. Ends the output with a newline. +# # a0 - String pointer. # a1 - String length. .type _write_error, @function @@ -306,3 +307,120 @@ _put_char: _get: lw a0, (a0) ret + +# Searches for the occurences of a character in the given memory block. +# +# Parameters: +# a0 - Memory block. +# a1 - Needle. +# a2 - Memory size. +# +# Sets a0 to the pointer to the found character or to null if the character +# doesn't occur in the memory block. +.type _memchr, @function +_memchr: +.Lmemchr_loop: + beqz a2, .Lmemchr_nil # Exit if the length is 0. + + lbu t0, (a0) # Load the character from the memory block. + beq t0, a1, .Lmemchr_end # Exit if the character was found. + + # Otherwise, continue with the next character. + addi a0, a0, 1 + addi a2, a2, -1 + + j .Lmemchr_loop + +.Lmemchr_nil: + li a0, 0 + +.Lmemchr_end: + ret + +# Locates a substring. +# +# Parameters: +# a0 - Haystack. +# a1 - Haystack size. +# a2 - Needle. +# a3 - Needle size. +# +# Sets a0 to the pointer to the beginning of the substring in memory or to 0 +# if the substring doesn't occur in the block. +.type _memmem, @function +_memmem: + # Prologue. + addi sp, sp, -24 + sw ra, 20(sp) + sw s0, 16(sp) + addi s0, sp, 24 + + # Save preserved registers. They are used to keep arguments. + sw s1, 12(sp) + sw s2, 8(sp) + sw s3, 4(sp) + sw s4, 0(sp) + + mv s1, a0 + mv s2, a1 + mv s3, a2 + mv s4, a3 + +.Lmemmem_loop: + blt s2, s3, .Lmemmem_nil # Exit if the needle length is greater than memory. + + mv a0, s1 + mv a1, s3 + mv a2, s4 + call _memcmp + + mv t0, a0 # memcmp result. + mv a0, s1 # Memory pointer for the case the substring was found. + beqz t0, .Lmemmem_end + + addi s1, s1, 1 + add s2, s2, -1 + + j .Lmemmem_loop + +.Lmemmem_nil: + li a0, 0 + +.Lmemmem_end: + + # Restore the preserved registers. + lw s1, 12(sp) + lw s2, 8(sp) + lw s3, 4(sp) + lw s4, 0(sp) + + # Epilogue. + lw ra, 20(sp) + lw s0, 16(sp) + add sp, sp, 24 + ret + +# Copies memory. +# +# Parameters: +# a0 - Destination. +# a1 - Source. +# a2 - Size. +# +# Preserves a0. +.type _memcpy, @function +_memcpy: + mv t0, a0 + +.Lmemcpy_loop: + beqz a2, .Lmemcpy_end + + lbu t1, (a1) + sb t1, (a0) + + addi a0, a0, 1 + addi a1, a1, 1 + +.Lmemcpy_end: + mv a0, t0 + ret -- cgit v1.2.3