asmtutorials/x86_64/functions.asm

81 lines
2.1 KiB
NASM

;; This is an includes file. It doesn't have its own compilation
;; capabilities. There is no namespacing in assembly language;
;; try not to use these names in your own code.
;; sys/unistd_32.h
%define SYS_write 1
%define SYS_exit 60
;; unistd.h
%define STDOUT 1
;; A single null-terminated line feed.
section .data
_lf db 0ah, 00h
section .text
;; strlen() function. Takes rdx as an argument - the pointer to
;; the initial string. Returns rdx as the result - the length of
;; the string.
strlen:
push rsi
mov rsi, rdx
strlen_next:
cmp byte [rdx], 0
jz strlen_done
inc rdx
jmp strlen_next
strlen_done:
sub rdx, rsi
pop rsi
ret
;; puts() function - puts a string to the console. Takes RSI as
;; its only argument - the pointer to the beginning of the string.
puts:
push rcx ; syscall uses RCX itself
push rdx ; RDX (data) is used as the length of the message
push rax ; RAX is the instruction to WRITE
push rdi ; RDI (destination) is used as an instruction to WRITE
mov rdx, rsi
call strlen
;; Because I chose to use RDX as the target for strlen, I don't need to
;; do the pop/push dance as I did in the 32-bit version.
mov rdi, STDOUT ; using STDOUT (see definition above)
mov rax, SYS_write ; Using WRITE in 32-bit mode?
syscall
;; Likewise, because I chose RSI as the Source (pointer) to my
;; message, it remains unchanged during the lifetime of this
;; routine (unless there are any bugs in strlen) and I don't
;; have to restore it either.
pop rdi
pop rax
pop rdx
pop rcx
ret
putslf:
call puts ; Print the string
push rsi ; Preserve this register
mov rsi, _lf
call puts
pop rsi
ret
;; exit(). Straight from the original.
exit_program:
mov rdi, 0
mov rax, SYS_exit
syscall