From 1bff04e860ab785a767e222800323b42ae6bfdba Mon Sep 17 00:00:00 2001 From: hasslesstech Date: Sun, 15 Sep 2024 16:53:50 +0300 Subject: [PATCH] initial commit --- Makefile | 10 ++++++ lib/strutils.h | 1 + src/main.c | 16 ++++++++++ src/strutils.asm | 81 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 108 insertions(+) create mode 100644 Makefile create mode 100644 lib/strutils.h create mode 100644 src/main.c create mode 100644 src/strutils.asm diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..03d4832 --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +ASMFLAGS = +CFLAGS = -I lib -O3 + +build: src/strutils.asm src/main.c + nasm $(ASMFLAGS) -f elf64 -o out/strutils.o src/strutils.asm + #gcc $(CFLAGS) -o out/main.o -c src/main.c + #ld -o bin/main out/main.o out/strutils.o + gcc $(CFLAGS) -o bin/main \ + src/main.c \ + out/strutils.o diff --git a/lib/strutils.h b/lib/strutils.h new file mode 100644 index 0000000..c361f54 --- /dev/null +++ b/lib/strutils.h @@ -0,0 +1 @@ +void count_vowels(char *str, int *result); diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..1b906f8 --- /dev/null +++ b/src/main.c @@ -0,0 +1,16 @@ +#include +#include "strutils.h" + +int main(void) +{ + char source_string[1024]; + int amount_of_vowels; + + fgets(source_string, 1023, stdin); + + count_vowels(source_string, &amount_of_vowels); + + printf("%d\n", amount_of_vowels); + + return 0; +} diff --git a/src/strutils.asm b/src/strutils.asm new file mode 100644 index 0000000..d355090 --- /dev/null +++ b/src/strutils.asm @@ -0,0 +1,81 @@ +global count_vowels + +section .note.GNU-stack + +section .text + +vowel_found: + inc r12 + jmp next_char + +; void count_vowels(char *str, int *result); +; | | +; v v +; %rdi %rsi +count_vowels: + ; back up the pointers + push rsi + push rdi + + ; find string length + mov rcx, 1024 + mov al, 0 + ; rdi is set by caller + + repne scasb + + ; not wasting time on JNE + ; as ZF should always equal to 1 + + mov rdi, rcx + mov rcx, 1024 + sub rcx, rdi ; strlen -> rcx + + ; recover *str + pop rdi + + ; loop through the letters + xor r12, r12 ; reset counter + + loop1: + mov bl, [rdi+rcx-1] + cmp bl, 0x3F + jle next_char ; if the symbol code <= 0x3F, + ; it can never be a letter + + and bl, 0x5F ; 0x5F -> 01011111 + ; ^ ^ + ; | cut off 6th bit to cast + ; | all letters to uppercase + ; | + ; cut off any signed nonsense + + cmp bl, 'A' + je vowel_found + + cmp bl, 'Y' + jg next_char + je vowel_found + + cmp bl, 'E' + je vowel_found + + cmp bl, 'I' + je vowel_found + + cmp bl, 'O' + je vowel_found + + cmp bl, 'U' + je vowel_found + + next_char: + dec rcx + jnz loop1 + + pop rsi + + ; copy result to target memory location + mov [rsi], r12d + + ret