diff options
author | Joseph Hunkeler <jhunkeler@gmail.com> | 2017-11-28 16:49:24 -0500 |
---|---|---|
committer | Joseph Hunkeler <jhunkeler@gmail.com> | 2017-11-28 16:49:24 -0500 |
commit | 1dd05ebe61c95985b16d170bf2d3f081a02dfd7d (patch) | |
tree | 216d65aa993cba84c1b58e7152efd516b37121cc /string.asm | |
download | minos-1dd05ebe61c95985b16d170bf2d3f081a02dfd7d.tar.gz |
Initial commit
Diffstat (limited to 'string.asm')
-rw-r--r-- | string.asm | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/string.asm b/string.asm new file mode 100644 index 0000000..4000afb --- /dev/null +++ b/string.asm @@ -0,0 +1,174 @@ +%ifndef _STRING_ASM +%define _STRING_ASM + +; stack direction +; --------------- +; + = external +; - = local +; +; ^ must be getting old D: +; + +; calling conventions +; push COUNT +; push SOURCE +; push DESTINATION +; call FUNCTION +; add sp, 6 (^ in the case of three WORDS) +; +; In C, for instance, this translate to: +; FUNCTION (DESTINATION, SOURCE, COUNT); + +memset: + ; Set memory with byte value + push bp ; setup stack frame + mov bp, sp ; ... + push si + push di + push cx + + mov di, [bp + 4] ; destination address + mov ax, [bp + 6] ; requested byte value + mov cx, [bp + 8] ; count + + cld ; will decrement address ES:DI + rep stosb ; while cx > 0 + ; store byte AL in ES:DI + + pop cx + pop di + pop si + mov sp, bp + pop bp + ret + + +memcpy: + push bp ; setup stack frame + mov bp, sp ; ... + + mov di, [bp + 4] ; destination buffer + mov si, [bp + 6] ; source buffer + mov cx, [bp + 8] ; count of characters to move + + cld + rep movsb + + mov sp, bp + pop bp + ret + + +strlen: + ; Determine length of null terminated string + ; NOTE: 64k limit imposed + push bp ; setup stack frame + mov bp, sp ; ... + push cx + push si + + xor cx, cx ; cx is counter + xor ax, ax ; ax is return value + mov si, [bp + 2] ; string address +.loop: + lodsb ; load byte from ES:SI into AL + cmp al, 0 ; zero? + je .return ; if so, we're done + inc cx ; if not, keep going + jc .crash ; if we roll over CX the carry flag will be set (that's bad) + + jmp .loop + +.crash: + stc ; force carry flag on failure + +.return: + clc + mov ax, cx + pop si + pop cx + mov sp, bp + pop bp + ret + + +strnchr: + ; Find first occurence of character in a string + push bp ; setup stack frame + mov bp, sp ; ... + push cx + push dx + push si + + xor ax, ax ; ax is return value + mov si, [bp + 4] ; string address + mov dx, [bp + 6] ; needle character + mov cx, [bp + 8] ; counter +.loop: + lodsb ; load byte at si + cmp al, dl ; same as needle? + je .return ; if true: return + + dec cx ; decrement counter + jne .loop ; counter zero? + +.return: + mov ax, cx ; return index of character + pop si + pop dx + pop cx + mov sp, bp + pop bp + ret + + +strncmp: + ; Determine difference between two strings + push bp ; setup stack frame + mov bp, sp ; ... + push bx ; save registers + push dx + push si + push di + + mov di, [bp + 4] ; string2 address + mov si, [bp + 6] ; string1 address + mov cx, [bp + 8] ; limit to compare + +.loop: + mov bx, [si] ; string1 + mov dx, [di] ; string2 + inc si ; next address, string1 + inc di ; next address, string2 + dec cx ; decrease byte counter + + cmp bx, dx ; compare bytes + jne .diff ; Just die if not-equal + + cmp cx, 0 ; If equal, check for null termination + jne .loop + +.diff: + cmp bx, dx + jg .s1_larger + jl .s1_smaller + je .return + +.s1_smaller: + mov ax, -1 + jmp .return + +.s1_larger: + mov ax, cx + +.return: + pop di ; cleanup stack + pop si + pop dx + pop bx + mov sp, bp + pop bp + ret + + +%endif ; _STRING_ASM |