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