WRITE
PROCEDURE
1.identify the corresponding number for the syscall (write)
- cat /usr/include/x86_64-linux-gnu/asm/unistd_64.h
#ifndef _ASM_X86_UNISTD_64_H
#define _ASM_X86_UNISTD_64_H 1
#define __NR_read 0
#define __NR_write 1
#define __NR_open 2
#define __NR_close 3
#define __NR_stat 4
#define __NR_fstat 5
2.research how to use the required syscall (write)
- root@dev:~$ man -s 2 write
...SNIP...
ssize_t write(int fd, const void *buf, size_t count);
- File Descriptor fd to be printed to (usually 1 for stdout)
- The address pointer to the string to be printed
- The length to be printed
3.Save registers to stack
- push ...
4.Set its syscall number in rax
- mov rax, 1
- rax is also used for storing the return value of a syscall or a function. So,
if we were expecting to get a value back from a syscall/function, it will be
in rax.
5.Set its arguments in the registers
- rdi -> 1 (for stdout)
rsi -> 'Fibonacci Sequence:\n' (pointer to our string)
rdx -> 20 (length of our string)
6.Use the syscall assembly instruction to call it
7.gracefully exit syscalls
- root@dev:~$ grep exit /usr/include/x86_64-linux-gnu/asm/unistd_64.h
#define __NR_exit 60
#define __NR_exit_group 231
- root@dev:~$ man -s 2 exit
...SNIP...
void _exit(int status);
- mov rax, 60
mov rdi, 0
syscall
section .data
message db "Fibonacci Sequence:", 0x0a
msg_len equ $ - message ; $ is the current address, so $ - message = length
section .text
global _start
_start:
mov rax, 1 ; rax: syscall number 1
mov rdi, 1 ; rdi: fd 1 for stdout
mov rsi,message ; rsi: pointer to message
mov rdx, msg_len
;mov rdx, 20 ; rdx: print length of 20 bytes
syscall ; call write syscall to the intro message
xor rax, rax ; initialize rax to 0
xor rbx, rbx ; initialize rbx to 0
inc rbx ; increment rbx to 1
loopFib:
add rax, rbx ; get the next number
xchg rax, rbx ; swap values
cmp rbx, 10 ; do rbx - 10
js loopFib ; jump if result is <0
;graceful syscall exit
mov rax, 60
mov rdi, 0
syscall
Last updated