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