From 2f5e3202dbe4db413080ff51d7b74bb929cb534c Mon Sep 17 00:00:00 2001 From: Kwarde Date: Mon, 23 Jun 2025 15:07:55 +0200 Subject: [PATCH] min[u](),max[u](),islower(),isupper(),print(),puts(),strlen(),strcpy(),strcat() --- console.asm | 46 ++++++++++++ core.asm | 96 +++++++++++++++++++++++++ string.asm | 67 ++++++++++++++++++ tests.asm | 198 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 407 insertions(+) create mode 100644 console.asm create mode 100644 core.asm create mode 100644 string.asm create mode 100644 tests.asm diff --git a/console.asm b/console.asm new file mode 100644 index 0000000..e73c768 --- /dev/null +++ b/console.asm @@ -0,0 +1,46 @@ +extern strlen + +section .rodata + NL db 10 +section .text + global print + global puts + +;----- print (char* string) -----; +; return value: N/A +print: + push rbp + mov rbp, rsp + + push rdi + sub rsp, 8 + call strlen + mov rdx, rax + add rsp, 8 + pop rdi + mov rax, 1 + mov rsi, rdi + mov rdi, 1 + syscall + + leave + ret +;----- puts (char* string) -----; +; return value: N/A +puts: + push rbp + mov rbp, rsp + + push rdi + sub rsp, 8 + call print + add rsp, 8 + pop rdi + mov rax, 1 + mov rdi, 1 + mov rsi, NL + mov rdx, 1 + syscall + + leave + ret diff --git a/core.asm b/core.asm new file mode 100644 index 0000000..7845182 --- /dev/null +++ b/core.asm @@ -0,0 +1,96 @@ +section .text + global min + global minu + global max + global maxu + global islower + global isupper + +;----- min(int a, int b) -----; +; return value: lowest value +min: + push rbp + mov rbp, rsp + + mov rax, rdi + cmp rdi, rsi + jl .quit + mov rax, rsi + + .quit: + leave + ret +;----- minu(unsigned int a, unsigned int b) -----; +; return value: lowest value +minu: + push rbp + mov rbp, rsp + + mov rax, rdi + cmp rdi, rsi + jb .quit + mov rax, rsi + + .quit: + leave + ret +;----- max(int a, int b) -----; +; return value: highest value +max: + push rbp + mov rbp, rsp + + mov rax, rdi + cmp rdi, rsi + jg .quit + mov rax, rsi + + .quit: + leave + ret +;----- maxu(unsigned int a, unsigned int b) -----; +; return value: highest value +maxu: + push rbp + mov rbp, rsp + + mov rax, rdi + cmp rdi, rsi + ja .quit + mov rax, rsi + + .quit: + leave + ret +;----- islower(char* c) -----; +; return value: 1 (character is in range of 'a'-'z') or 0 (character is nog in range of 'a'-'z') +islower: + push rbp + mov rbp, rsp + + xor rax, rax + cmp byte [rdi], 'a' + jb .quit + cmp byte [rdi], 'z' + ja .quit + mov rax, 1 + + .quit: + leave + ret +;----- isupper(char* c) -----; +; return value: 1 (character is in range of 'A'-'Z') or 0 (character is not in range of 'A'-'Z') +isupper: + push rbp + mov rbp, rsp + + xor rax, rax + cmp byte [rdi], 'A' + jb .quit + cmp byte [rdi], 'Z' + ja .quit + mov rax, 1 + + .quit: + leave + ret diff --git a/string.asm b/string.asm new file mode 100644 index 0000000..2681185 --- /dev/null +++ b/string.asm @@ -0,0 +1,67 @@ +section .text + global strlen + global strcpy + global strcat + +;----- strlen(char* str) -----; +; return value: amount of characters before EOS was found +strlen: + push rbp + mov rbp, rsp + + xor rax, rax + .findEOS: + cmp byte [rdi+rax], 0x0 + je .quit + inc rax + jmp .findEOS + + .quit: + leave + ret +;----- strcpy(char* dest, char* src) -----; +; return value: pointer to dest or NULL if nothing was copied +strcpy: + push rbp + mov rbp, rsp + + push rdi + sub rsp, 8 + xor rax, rax + xor rcx, rcx + .loop: + cmp byte [rsi], 0x0 + je .0f + mov r10b, byte [rsi] + mov byte [rdi], r10b + inc rsi + inc rdi + inc rcx + jmp .loop + + .0f: + pop rax + add rsp, 8 + cmp rcx, 0 + jne .quit + xor rax, rax + + .quit: + leave + ret +;----- strcat(char* dest, char* src) -----; +; return value: pointer to dest +strcat: + push rbp + mov rbp, rsp + + push rdi + sub rsp, 8 + call strlen + add rdi, rax + call strcpy + add rsp, 8 + pop rdi + + leave + ret diff --git a/tests.asm b/tests.asm new file mode 100644 index 0000000..6af8e9c --- /dev/null +++ b/tests.asm @@ -0,0 +1,198 @@ +extern printf + +;core.asm +extern min +extern minu +extern max +extern maxu +extern islower +extern isupper +;console.asm +extern print +extern puts +;string.asm +extern strlen +extern strcpy +extern strcat + +section .rodata + num1 dq 13 + num2 dq -25 + num3 equ 60 + msgNums db "> num1: %d",10,"> num2: %d",10,"> num3: %d",10,0 + msgMin db "min(num1, num2): %d",10,0 + msgMin2 db "minu(num1, num3): %d",10,0 + msgMin3 db "min(num2, num3): %d",10,0 + msgMax db "max(num1, num2): %d",10,0 + msgMax2 db "maxu(num1, num3): %d",10,0 + msgMax3 db "max(num2, num3): %d",10,0 + msgPrint db "print() test",0 + msgPuts db " and puts() test",0 + str1 db "Hello, world!",0 + str2 db "Hello World!",0 + str3 db "Howdy environment!",0 + msgStrings db "> str1: %s",10,"> str2: %s",10,"> str3: %s",10,0 + msgStrlen db "strlen(str1): %d",10,0 + msgStrlen2 db "strlen(str3): %d",10,0 + msgIslower db "islower(str1[0]): %d",10,0 + msgIslower2 db "islower(str1[1]): %d",10,0 + msgIsupper db "isupper(str1[0]): %d",10,0 + msgIsupper2 db "isupper(str1[1]): %d",10,0 + msgStrcpy db "strcpy(str1Copy, str1): %s",10,0 + msgStrcat db "strcat(str1Copy, str3): %s",10,0 + msgStrlen3 db "strlen(str1Copy): %d",10,0 +section .data +section .bss + str1Copy resb 32 +section .text + global main +main: + push rbp + mov rbp, rsp + + ; PRINT: num1, num2, num3 + xor rax, rax + lea rdi, [rel msgNums] + mov rsi, [rel num1] + mov rdx, [rel num2] + mov rcx, num3 + call printf + + ; TEST: min() + mov rdi, [rel num1] + mov rsi, [rel num2] + call min + mov rsi, rax + xor rax, rax + lea rdi, [rel msgMin] + call printf + ; + mov rdi, [rel num1] + mov rsi, num3 + call minu + mov rsi, rax + xor rax, rax + lea rdi, [rel msgMin2] + call printf + ; + mov rdi, [rel num2] + mov rsi, num3 + call min + mov rsi, rax + xor rax, rax + lea rdi, [rel msgMin3] + call printf + + ; TEST: max() + mov rdi, [rel num1] + mov rsi, [rel num2] + call max + mov rsi, rax + xor rax, rax + lea rdi, [rel msgMax] + call printf + ; + mov rdi, [rel num1] + mov rsi, num3 + call maxu + mov rsi, rax + xor rax, rax + lea rdi, [rel msgMax2] + call printf + ; + mov rdi, [rel num2] + mov rsi, num3 + call max + mov rsi, rax + xor rax, rax + lea rdi, [rel msgMax3] + call printf + + ; TEST: print() + lea rdi, [rel msgPrint] + call print + ; TEST: puts() + lea rdi, [rel msgPuts] + call puts + + ; PRINT: str1, str2, str3 + xor rax, rax + lea rdi, [rel msgStrings] + lea rsi, [rel str1] + lea rdx, [rel str2] + lea rcx, [rel str3] + call printf + + ; TEST: strlen() + lea rdi, [rel str1] + call strlen + mov rsi, rax + xor rax, rax + lea rdi, [rel msgStrlen] + call printf + ; + lea rdi, [rel str3] + call strlen + mov rsi, rax + xor rax, rax + lea rdi, [rel msgStrlen2] + call printf + + ; TEST: islower() + lea rdi, [rel str1] + call islower + mov rsi, rax + xor rax, rax + lea rdi, [rel msgIslower] + call printf + ; + lea rdi, [rel str1+1] + call islower + mov rsi, rax + xor rax, rax + lea rdi, [rel msgIslower2] + call printf + + ; TEST: isupper() + lea rdi, [rel str1] + call isupper + mov rsi, rax + xor rax, rax + lea rdi, [rel msgIsupper] + call printf + ; + lea rdi, [rel str1+1] + call isupper + mov rsi, rax + xor rax, rax + lea rdi, [rel msgIsupper2] + call printf + + ; TEST: strcpy() + lea rdi, [rel str1Copy] + lea rsi, [rel str1] + call strcpy + xor rax, rax + lea rdi, [rel msgStrcpy] + lea rsi, [rel str1Copy] + call printf + + ; TEST: strcat() + lea rdi, [rel str1Copy] + lea rsi, [rel str3] + call strcat + xor rax, rax + lea rdi, [rel msgStrcat] + lea rsi, [rel str1Copy] + call printf + + ; TEST: strlen() for str1Copy + lea rdi, [rel str1Copy] + call strlen + mov rsi, rax + xor rax, rax + lea rdi, [rel msgStrlen3] + call printf + + leave + ret