count words
This commit is contained in:
parent
00bd026d74
commit
980b66cae9
@ -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
|
||||
|
||||
49
lang/asem.s
49
lang/asem.s
@ -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
|
||||
BIN
lang/debug
BIN
lang/debug
Binary file not shown.
BIN
lang/obj/asem.o
BIN
lang/obj/asem.o
Binary file not shown.
BIN
lang/obj/balloc.o
Normal file
BIN
lang/obj/balloc.o
Normal file
Binary file not shown.
BIN
lang/obj/split.o
Normal file
BIN
lang/obj/split.o
Normal file
Binary file not shown.
100
lang/src/asem.s
Normal file
100
lang/src/asem.s
Normal file
@ -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
|
||||
26
lang/src/balloc.s
Normal file
26
lang/src/balloc.s
Normal file
@ -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
|
||||
43
lang/src/split.s
Normal file
43
lang/src/split.s
Normal file
@ -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
|
||||
Loading…
x
Reference in New Issue
Block a user