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