diff --git a/lang/Makefile b/lang/Makefile index 8b4ffd8..3f76ebb 100644 --- a/lang/Makefile +++ b/lang/Makefile @@ -1,9 +1,16 @@ -SRC := asem.s - +SRCDIR := src +SRC := $(addprefix $(SRCDIR)/, $(addsuffix .s, asem balloc split)) OBJDIR := obj -OBJ := $(OBJDIR)/$(SRC:.s=.o) +OBJ := $(addprefix $(OBJDIR)/, $(notdir $(SRC:.s=.o))) -all: - nasm -felf64 -g $(SRC) -o $(OBJ) +$(shell mkdir -p $(OBJDIR)) + +all: $(OBJ) ld -o debug $(OBJ) -nostdlib -static + +$(OBJDIR)/%.o: $(SRCDIR)/%.s + nasm -felf64 -g $< -o $@ + +clean: + rm -rf $(OBJDIR) debug diff --git a/lang/asem.s b/lang/asem.s deleted file mode 100644 index 3834db9..0000000 --- a/lang/asem.s +++ /dev/null @@ -1,49 +0,0 @@ -%define DEF_BUFFER_LEN 4096 -%define INPUT_LENGTH 64 - -; rax -- syscall - -; type widths - -section .data - message: db "Hello World!", 0xA, 0 ; hello - message_length: equ $-message - -section .bss - arr: resb DEF_BUFFER_LEN - -section .text - global _start - -print_string: - push rbp - push rdx - mov rbp, rsp ; set up stack frame - - mov rax, 1 ; sys_write - - pop rdx - pop rbp - -exit: - mov rax, 60 - syscall - -strlen: - push rcx - xor rcx, rcx -.loop: - cmp byte [rdi + rcx], 0 - jz .done - inc rcx - jmp .loop -.done: - mov rax, rcx - pop rcx - ret - -_start: - mov rdi, message ; prepare first arg -> string addr to rdi - call strlen - mov rdi, rax - call exit diff --git a/lang/debug b/lang/debug deleted file mode 100755 index 583635e..0000000 Binary files a/lang/debug and /dev/null differ diff --git a/lang/obj/asem.o b/lang/obj/asem.o index a4b0676..9af0979 100644 Binary files a/lang/obj/asem.o and b/lang/obj/asem.o differ diff --git a/lang/obj/balloc.o b/lang/obj/balloc.o new file mode 100644 index 0000000..38ad05f Binary files /dev/null and b/lang/obj/balloc.o differ diff --git a/lang/obj/split.o b/lang/obj/split.o new file mode 100644 index 0000000..3abbb49 Binary files /dev/null and b/lang/obj/split.o differ diff --git a/lang/out b/lang/out deleted file mode 100755 index 7573671..0000000 Binary files a/lang/out and /dev/null differ diff --git a/lang/src/asem.s b/lang/src/asem.s new file mode 100644 index 0000000..83703ac --- /dev/null +++ b/lang/src/asem.s @@ -0,0 +1,100 @@ +%define DEF_BUFFER_LEN 4096 +%define INPUT_LENGTH 64 + +extern split + +section .data + message: db "Hello World!", 0xA, 0 + message_length: equ $-message + filepath: db "./test.c" + +section .bss + file_content_buffer: resb DEF_BUFFER_LEN + +section .text + global _start + +open_file: + mov rax, 2 ; sys_open + + syscall + ret + +close_file: + mov rax, 3 ; sys_close + + syscall + ret + +read_file_bytes: ; read(RDI: int fd, RSI: char *buffer, RDX: size_t size) + mov rax, 0 ; sys_read + syscall ; + ret + +print_string: ; print_string(RDI: char *string) + call strlen + + mov rdx, rax ; string length + + mov rsi, rdi + mov rdi, 1 ; stdout + mov rax, 1 ; sys_write + syscall + + ret + +exit: + mov rax, 60 + syscall + +strlen: ; strlen(RDI: char *str) + push rcx ; save counter + xor rcx, rcx +.loop: ; loop until '\0' character + cmp byte [rdi + rcx], 0 + jz .done + inc rcx + jmp .loop +.done: + mov rax, rcx ; mov return value to rax + pop rcx ; restore counter + ret + +_start: + mov rdi, message ; prepare first arg -> string addr to rdi + call print_string + + mov rdi, rax + push rax ; save rax + push rdi ; save rdi since arg comes into it + + mov rdi, filepath ; filepath for open call + mov rsi, 0 ; O_RDONLY flag + call open_file + + mov rbx, rax ; mov new fd to rbx + + mov rdi, rbx ; first arg: mov fd to rdi for read call + mov rsi, file_content_buffer ; 2nd arg: buffer + mov rdx, 15 ; 3rd arg: read len + + call read_file_bytes + mov byte [file_content_buffer + 15], 0xA ; newline + mov byte [file_content_buffer + 16], 0x0 ; 0 terminate string + + push rdi ; save fd + mov rdi, rsi ; stdout fd + + call print_string + pop rdi ; restore fd + + call close_file + + mov rdi, rsi + mov rsi, 0x20 ; ' ' space character + call split + +.exit_early: + mov rdi, rax + + call exit diff --git a/lang/src/balloc.s b/lang/src/balloc.s new file mode 100644 index 0000000..f8a0663 --- /dev/null +++ b/lang/src/balloc.s @@ -0,0 +1,26 @@ +global balloc + +brk_find_break: ; RAX: long brk(0) + mov rdi, 0x0 + mov rax, 0xC ; sys_brk + syscall + ret + +balloc: ; RAX: long basic_malloc(RDI: size_t n, RSI void **heap_begin_ptr) + cmp dword [rsi], 0 ; check if heap_begin_ptr exist + jne .allocate ; allocate normally if exists + + push rdi + + call brk_find_break + + mov qword [rsi], rax ; get heap beginning + pop rdi + +.allocate: + mov rax, qword [rsi] + add rdi, rax + mov rax, 0xC ; sys_brk + + syscall + ret diff --git a/lang/src/split.s b/lang/src/split.s new file mode 100644 index 0000000..7105820 --- /dev/null +++ b/lang/src/split.s @@ -0,0 +1,43 @@ +global split ; export split + +section .text + +count_splits: ; RAX: int count_splits(RDI: char *, RSI: int c) + push rbx + xor rcx, rcx + xor rbx, rbx +.loop: + cmp byte [rdi + rcx], 0 + jz .done + cmp byte [rdi + rcx], sil + jne .skip + inc rbx +.skip: + inc rcx + jmp .loop +.done: + mov rax, rbx + pop rbx + ret + +split: ; RAX: char ** split(RDI: char *str, RSI: int c) + push rbp + mov rbp, rsp ; save base pointer + + ; int count = [ rbp - 4 ] + + sub rsp, 4 ; allocate local vars + + call count_splits + + mov rsp, rbp + pop rbp + + ret + + ; count = count_splits() + mov [rbp - 4], rax + + pop rbp + + ret