diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.o diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index bb720ef..0000000 --- a/Dockerfile +++ /dev/null @@ -1,11 +0,0 @@ -FROM ubuntu:latest - -RUN apt-get update && apt-get install -y nasm gcc gdb vim - -COPY main.asm /app/main.asm - -WORKDIR /app -RUN nasm -f elf64 main.asm -o main.o -RUN ld main.o -o main - -CMD ["./main"] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f6cffca --- /dev/null +++ b/Makefile @@ -0,0 +1,21 @@ +ASM = as # GNU Assembler +LD = gcc # GCC Linker +LD_FLAGS = -nostartfiles + +SRC = factorial.s +OBJ = factorial.o +OUT = factorial + +all: $(OUT) + +$(OBJ): $(SRC) + $(ASM) $(SRC) -o $(OBJ) + +$(OUT): $(OBJ) + $(LD) $(LD_FLAGS) $(OBJ) -o $(OUT) + +run: all + ./$(OUT) + +clean: + rm -f $(OBJ) $(OUT) diff --git a/README.md b/README.md index db018aa..756cee7 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,3 @@ # Assembly Project Demonstration - Factorial with Recursion Demonstrate how functoin calls work in assembly by using a factorial recursion example. - -## Build - -```bash -docker build -t asm . -``` - -## Run - -```bash -docker run asm -``` diff --git a/factorial b/factorial new file mode 100755 index 0000000..384a46d Binary files /dev/null and b/factorial differ diff --git a/factorial.c b/factorial.c new file mode 100644 index 0000000..013b30d --- /dev/null +++ b/factorial.c @@ -0,0 +1,22 @@ +#include + +int factorial(int n) +{ + if (n <= 1) + { + return n; + } + + return n * factorial(n - 1); +} + +int main(void) +{ + int f; + + f = factorial(5); + + printf("%d\n", f); + + return 0; +} diff --git a/factorial.s b/factorial.s new file mode 100644 index 0000000..0979c06 --- /dev/null +++ b/factorial.s @@ -0,0 +1,72 @@ +.intel_syntax noprefix # allow mov rax, 1 syntax in GAS (GNU Assembly) +.global _start + +# factorial +# - rdi as input number +# - rax as result +factorial: + push rbp + mov rbp, rsp + + cmp rdi, 1 + jle base_case # if n <= 1 return 1 + + push rdi # save n + dec rdi # rdi = n-1 + call factorial # rax = factorial(n-1) + + pop rdx # rdx = original n + imul rax, rdx # rax = factorial(n-1) * n + jmp done + +base_case: + mov rax, 1 + +done: + mov rsp, rbp + pop rbp + ret + +print_rax_digit: + sub rsp, 16 + + mov rbx, 10 + + # ones digit + xor rdx, rdx + mov rcx, rax + div rbx + add dl, '0' + mov [rsp+2], dl + + # tens digit + xor rdx, rdx + mov rcx, rax + div rbx + add dl, '0' + mov [rsp+1], dl + + # hundreds digit + add al, '0' + mov [rsp], al + + mov rax, 1 + mov rdi, 1 + mov rsi, rsp + mov rdx, 3 + syscall + + add rsp, 16 + ret + +_start: + mov rdi, 5 # Use 5 for our example input + mov rax, 1 # Set starting result to 1 + + call factorial + + call print_rax_digit + + mov rax, 60 # syscall exit - 64 bit + mov rdi, 0 # exit code + syscall diff --git a/main.asm b/main.asm deleted file mode 100644 index e69de29..0000000