commit 59c0e74640fe79ef30b05c13505fba5b68787fd1 Author: Tovi Jaeschke Date: Tue Mar 26 16:27:23 2019 +1030 ASM tutorials diff --git a/calc_str_len.asm b/calc_str_len.asm new file mode 100644 index 0000000..7e5562b --- /dev/null +++ b/calc_str_len.asm @@ -0,0 +1,39 @@ +; calc_str_len.asm +; Prints calculates the length of the string "Hello, world!" and prints to stdout +; Compile with "nasm -f elf64 calc_str_len.asm && ld calc_str_len.o -o calc_str_len" + +.text: + global _start + +_start: + mov rax, msg ; move msg to rax register + call strlen ; call strlen subroutine + + mov rax, 1 ; system call for write + mov rdi, 1 ; file handle for stdout + syscall ; call kernel + + mov rax, 60 ; system call for exit + mov rdi, 0 ; exit code + syscall ; call kernel + + +strlen: + push rax ; push rax to stack + mov rbx, rax ; move rax value (msg variable) to rbx register + +calc_str_len: + cmp byte [rax], 0 ; check if the pointer of rax equals 0 (string delimeter) + jz exit_loop ; jump to "exit_loop" if zero flag has been set + inc rax ; increment rax (position along string) + jmp calc_str_len ; jump to start of loop + +exit_loop: + sub rax, rbx ; subtract rbx from rax to equal to length of bytes between them + mov rdx, rax ; rax will now equal the length of the string + pop rsi ; pop top value on stack to rsi for printing + ret + +.data: + ; initialize doubleword msg variable + msg db 'Hello, world!',0xa,0x0 diff --git a/fizzbuzz.asm b/fizzbuzz.asm new file mode 100644 index 0000000..affabe3 --- /dev/null +++ b/fizzbuzz.asm @@ -0,0 +1,57 @@ +; fizzbuzz.asm +; Prints numbers 1 to 100, however if the number is a multiple of 3 it will print Fizz, +; and if the number is a multiple of 5 it will print Buzz. If the number is a multiple +; of both, it will print FizzBuzz +; Compile with "nasm -f elf64 fizzbuzz.asm && ld fizzbuzz.o -o fizzbuzz" + +%include 'macros.asm' + +.text: + global _start + +_start: + mov rcx,0 ; counter + mov rsi,0 ; fizz check + mov rdi,0 ; buzz check + +loop: + inc rcx + +check_fizz: + mov rdx,0 + mov rax,rcx + mov rbx, 3 + div rbx + mov rsi,rdx + cmp rsi,0 + jne check_buzz + printStr f + +check_buzz: + mov rdx,0 + mov rax,rcx + mov rbx, 5 + div rbx + mov rdi,rdx + cmp rdi,0 + jne check_int + printStr b + +check_int: + cmp rsi,0 + je cont + cmp rdi,0 + je cont + printInt rcx + +cont: + printStr n + cmp rcx,99 + jle loop + exit 0 + +.data: + ; initialize doubleword msg variable + f db 'Fizz',0x0 + b db 'Buzz',0x0 + n db 0xA,0x0 diff --git a/hello_world.asm b/hello_world.asm new file mode 100644 index 0000000..732d66e --- /dev/null +++ b/hello_world.asm @@ -0,0 +1,21 @@ +; hello_world.asm +; Prints "Hello, world!" in 64 bit linux assembly written in intel syntax +; Compile with "nasm -f elf64 hello_world.asm && ld hello_world.o -o hello_world" + +.text: + global _start + +_start: + mov rax, 1 ; system call for write + mov rdi, 1 ; file handle for stdout + mov rsi, msg ; move msg variable to rsi register for printing + mov rdx, 14 ; length of the string + syscall ; call kernel + + mov rax, 60 ; system call for exit + mov rdi, 0 ; exit code + syscall ; call kernel + +.data: + ; initialize doubleword msg variable + msg db 'Hello, world!',0xa diff --git a/hello_world_macro.asm b/hello_world_macro.asm new file mode 100644 index 0000000..9419814 --- /dev/null +++ b/hello_world_macro.asm @@ -0,0 +1,16 @@ +; hello_world_macro.asm +; Prints "Hello, world!" using Assembly macros +; Compile with "nasm -f elf64 hello_world_macro.asm && ld hello_world_macro.o -o hello_world_macro" + +%include 'macros.asm' + +.text: + global _start + +_start: + printStr msg + exit 0 + +.data: + ; initialize doubleword msg variable + msg db 'Hello, world!',0x0 diff --git a/macros.asm b/macros.asm new file mode 100644 index 0000000..65ff9f5 --- /dev/null +++ b/macros.asm @@ -0,0 +1,103 @@ +; Collection of Assembly macros to make programming in assembly easier +; Include it with "%include 'macros.asm' + +section .data + newline db 0xA,0x0 + + ; Macro to calculate string length and print to stdout + %macro printStr 1 + ;; Store previous data + push rax + push rbx + push rcx + push rdx + push rdi + push rsi + + ;; Move first arg to rax + mov rax, %1 + ;; push rax to stack + push rax + ;; move 0 to rbx for loop counter + mov rbx,0 + ;; counts letters + %%printLoop: + inc rax + inc rbx + mov cl,[rax] + cmp cl,0 + jne %%printLoop + ;; sys_write + mov rax,1 + mov rdi,1 + pop rsi + mov rdx,rbx + syscall + + ;; pop values back to registers + + pop rsi + pop rdi + pop rdx + pop rcx + pop rbx + pop rax + + %endmacro + + %macro printStrLF 1 + push rax + mov rax,%1 + printStr rax + printStr newline + pop rax + %endmacro + + %macro printInt 1 + push rax + push rcx + push rdx + push rsi + + mov rax,%1 + mov rcx, 0 + + %%divideLoop: + inc rcx + mov rdx, 0 + mov rsi, 10 + idiv rsi + add rdx, 48 + push rdx + cmp rax, 0 + jnz %%divideLoop + + %%printLoop: + dec rcx + mov rax, rsp + printStr rax + pop rax + cmp rcx, 0 + jnz %%printLoop + + pop rsi + pop rdx + pop rcx + pop rax + + %endmacro + + %macro printIntLF 1 + push rax + mov rax, %1 + printInt rax + printStr newline + pop rax + %endmacro + + %macro exit 1 + mov rax,60 + mov rdi,%1 + syscall + %endmacro +