| @ -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 | |||||
| @ -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 | |||||
| @ -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 | |||||
| @ -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 | |||||
| @ -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 | |||||