From: Ralph Ronnquist Date: Sat, 29 May 2021 13:50:54 +0000 (+1000) Subject: added strlen, strncpy and realloc X-Git-Url: https://git.rrq.au/?a=commitdiff_plain;h=f2b2acd5d5c79e2d65854eef7e23f7323bc6c4f2;p=rrq%2Frrqforth.git added strlen, strncpy and realloc --- diff --git a/adoc/p_realloc.adoc b/adoc/p_realloc.adoc new file mode 100644 index 0000000..8c10c46 --- /dev/null +++ b/adoc/p_realloc.adoc @@ -0,0 +1,20 @@ +// stdio.asm: WORD p_realloc,'REALLOC',fasm + +anchor:p_realloc[] + +=== Word: reALLOC + +.... +Data stack: ( a m n -- a ) +.... + +"REALLOC" is a word that reallocates memory using mremap of address a +of size m to be size n bytes and returns the lowest address of the +allocated block. + +Note that this makes new page allocations for the process from the +kernel, and the granularity is in pages, i.e. a multiple of 4 kb. + +The memory is reampped using the MREMAP_MAYMOVE flag, + +See also <> diff --git a/adoc/p_strlen.adoc b/adoc/p_strlen.adoc new file mode 100644 index 0000000..5b5eacd --- /dev/null +++ b/adoc/p_strlen.adoc @@ -0,0 +1,12 @@ +// wordlists.asm: WORD p_strlen,'STRLEN',fasm + +anchor:p_strlen[] + +=== Word: STRLEN +.... +Data stack: ( s -- n ) +.... + +"STRLEN" is a function words that counts how many bytes there are from +s to the first NUL byte and returns that count, n, not including the +NUL byte. diff --git a/adoc/p_strncpy.adoc b/adoc/p_strncpy.adoc new file mode 100644 index 0000000..d92127b --- /dev/null +++ b/adoc/p_strncpy.adoc @@ -0,0 +1,11 @@ +// wordlists.asm: WORD p_strncpy,'STRNCPY',fasm + +anchor:p_strncpy[] + +=== Word: STRNCPY +.... +Data stack: ( s1 s2 n -- ) +.... + +"STRNCPY" is a function words that copies n bytes of byte sequence s1 +to s2. diff --git a/reference.adoc b/reference.adoc index fac097f..6237f82 100644 --- a/reference.adoc +++ b/reference.adoc @@ -1,7 +1,7 @@ = RRQFORTH Reference Documentation :author: Ralph Ronnquist -== Compilation words +== Compilation Words // include::compile.adoc[] include::adoc/p_allot.adoc[] include::separator.adoc[] @@ -47,6 +47,7 @@ include::adoc/p_state.adoc[] include::separator.adoc[] include::adoc/p_this_word.adoc[] +== Execution Control Words //include::control.adoc[] include::adoc/p_0branch.adoc[] include::separator.adoc[] @@ -68,7 +69,7 @@ include::adoc/p_ifbreak.adoc[] include::separator.adoc[] include::adoc/p_then.adoc[] -== Logic operation words +== Logic Operation Words //include::logic.adoc[] include::adoc/p_0equal.adoc[] include::separator.adoc[] @@ -100,7 +101,7 @@ include::adoc/p_within.adoc[] include::separator.adoc[] include::adoc/p_xor.adoc[] -== Math operation words +== Math Operation Words // include::math.adoc[] include::adoc/p_abs.adoc[] include::separator.adoc[] @@ -114,18 +115,14 @@ include::adoc/p_negate.adoc[] include::separator.adoc[] include::adoc/p_plus.adoc[] -== RRQFORTH main words +== RRQFORTH Main Words //include::rrqforth.adoc[] include::adoc/data_stack.adoc[] include::separator.adoc[] include::adoc/inline_code.adoc[] include::separator.adoc[] -include::adoc/p_0branch.adoc[] -include::separator.adoc[] include::adoc/p_args.adoc[] include::separator.adoc[] -include::adoc/p_branch.adoc[] -include::separator.adoc[] include::adoc/p_dodoes.adoc[] include::separator.adoc[] include::adoc/p_dofasm.adoc[] @@ -214,6 +211,8 @@ include::adoc/p_read_stream_char.adoc[] include::separator.adoc[] include::adoc/p_read_word.adoc[] include::separator.adoc[] +include::adoc/p_realloc.adoc[] +include::separator.adoc[] include::adoc/p_sp.adoc[] include::separator.adoc[] include::adoc/p_stream.adoc[] @@ -230,8 +229,12 @@ include::adoc/p_find.adoc[] include::separator.adoc[] include::adoc/p_forth.adoc[] include::separator.adoc[] +include::adoc/p_strlen.adoc[] +include::separator.adoc[] include::adoc/p_strncmp.adoc[] include::separator.adoc[] +include::adoc/p_strncpy.adoc[] +include::separator.adoc[] include::adoc/p_words.adoc[] == System calls diff --git a/stdio.asm b/stdio.asm index 865b7f0..9cf7611 100644 --- a/stdio.asm +++ b/stdio.asm @@ -2,9 +2,9 @@ ;;; Dynamic memory management. Allocated with MALLOC and released with ;;; MUNMAP (see below) - ;; ( size -- addr ) - ;; Allocates memory (using brk) WORD p_malloc,'MALLOC',fasm + ;; ( size -- addr ) + ;; Allocates memory (using mmap) pushr rsi ; pretend it's a FORTH word since it ; ends via sys_mmap_asm pop rax @@ -16,6 +16,15 @@ push qword 0 ; offset jmp sys_mmap_asm ; exit via sys_mmap + WORD p_realloc,'REALLOC',fasm + ;; ( addr old new -- ) + ;; Try remapping a given MMAP region of old size to a new size + ;; mremap(void *old_address, size_t old_size, + ;; size_t new_size, int flags, ... /* void *new_address */); + pushr rsi + push 1 ; MREMAP_MAYMOVE + jmp sys_mmap_asm ; exit via sys_mmap + ;;; ======================================== ;;; Input stream handling. ;;; diff --git a/wordlists.asm b/wordlists.asm index 44656e8..7daa428 100644 --- a/wordlists.asm +++ b/wordlists.asm @@ -38,27 +38,67 @@ p_words_END: popr rsi next + WORD p_strlen,'STRLEN',fasm + ;; ( chars -- n ) + ;; Determine length of NUL terminated byte sequence + pushr rsi + mov rsi,qword [rsp] + xor rcx,rcx + dec rcx + cld +p_strlen_LOOP: + inc rcx + lodsb + cmp al,0 + jne p_strlen_LOOP + mov qword [rsp],rcx + popr rsi + next + + WORD p_strncpy,'STRNCPY',fasm + ;; ( chars1 chars2 n -- ) + ;; Copy n bytes from chars1 to chars2. + pushr rsi + pop rcx + pop rdi + pop rsi + cmp rcx,0 + jle p_strncpy_END + cld +p_strncpy_LOOP: + movsb + dec rcx + jg p_strncpy_LOOP +p_strncpy_END: + popr rsi + next + WORD p_strncmp,'STRNCMP',fasm ;; ( chars1 chars2 n -- flag ) ;; Compare bytes until one is NUL, return <0, =0 or >0 to ;; indicate that chars1 is lesser, they are equal, or chars2 ;; is lesser in ascii ordering respectively. - pop rdx ; count - pop rbx ; chars2 - pop rax ; chars1 - xor rcx,rcx + pushr rsi + pop rcx ; count + pop rsi ; chars2 + pop rdi ; chars1 + xor rax,rax + cmp rcx,0 + jle p_strncmp_end ;; rax = chars1, rbx = chars2, cl = byte acc, rdx = length + cld p_strncmp_loop: - dec rdx - jl p_strncmp_end - mov cl,[rax] - inc rax - inc rbx - sub cl,[rbx-1] - je p_strncmp_loop - jmp p_strncmp_end + cmpsb + jne p_strncmp_diff + dec rcx + jg p_strncmp_loop +p_strncmp_diff: + xor rax,rax + mov al,[rsi-1] + sub al,[rdi-1] p_strncmp_end: - push rcx + push rax + popr rsi next WORD p_find,'FIND',fasm