The goal of libasm is to get familiar with x86_64 assembly by working with strings, numbers, functions, function pointers, and structures (linked lists) in nasm.
First, make sure you have nasm
, make
and either gcc
or clang
installed.
Clone the repository:
git clone https://github.com/Aktai0n/libasm-42Heilbronn.git libasm && cd libasm
Build the project with:
make test
this will build an archive named libasm.a
and an executeable named tester
To run all tests at once use
./tester
Or use
./tester [function_name]
with the specific function you want to test (e.g. strdup
, atoi_base
, ...) to test only a specific function
You can also provide multiple function names as arguments
If you want a more detailed output on what is being tested with you can rebuild the project with
make re VERBOSE=1
to enable verbose test output (only recommended for testing individual functions)
The available functions are:
size_t ft_strlen(const char* str);
char* ft_strcpy(char* dest, const char* src);
int ft_strcmp(const char* s1, const char* s2);
char* ft_strdup(const char* s);
ssize_t ft_write(int fd, const void* buf, size_t count);
ssize_t ft_read(int fd, void* buf, size_t count);
int ft_atoi_base(char* str, char* base);
void ft_list_push_front(t_list** begin_list, void* data);
int ft_list_size(t_list* begin_list);
void ft_list_sort(t_list** begin_list, int (*cmp)());
void ft_list_remove_if(t_list** begin_list, void* data_ref, int (*cmp)(), void (*free_fct)(void*));
t_list
is a struct defined as follows:
typedef struct s_list {
void* data;
struct s_list* next;
} t_list;
More information about each function can be found at inc/libasm.h
Note: This only applies to the x86_64 System V calling convention used in this project
A reference with the most commonly used x86_64 instructions and paradigms can be found here.
In assembly you work with registers
. Those are (since the introduction of x64) 64-bit wide memory spaces where values can be stored.
There are 16 Registers:
rax, rbx, rcx, rdx, rdi, rsi, rbp, rsp, r8, r9 ... r15
These can be divided into volatile and non-volatile registers.
Volatile registers are:
rax, rcx, rdx, r8 ... r11
The rest of them are non-volatile:
rbx, rdi, rsi, rbp, rsp, r12 ... r15
Furthermore, some of the registers are used for specific purposes:
-
rsp
: Holds the value of the stack pointer -
rax
: Holds the return value of a function call -
rdi
,rsi
,rdx
,rcx
,r8
,r9
: Used to pass the 1st to 6th parameter to functions - in this exact order. Further function arguments are passed on the stack. -
rbp
: Often used to save the value ofrsp
upon function entry and restore the value ofrsp
upon function exit. That's why it's often referred to as base pointer. -
EFLAGS
: A special register that is rarely set directly. Instead it holds specific flags that will be set / reset by comparison operations and read by conditional instructions.
Every line of code is divided into an instruction and the registers or memory regions that are affected by it. E.g.:
mov rax, 0
^^^ ^^^^^^
instruction affected register(s)
Pointers are dereferenced by putting the register the pointer is stored in between [] and specifying how many bytes should be read from the pointer:
mov BYTE [rax], 0 ; move zero into the Byte that rax points to
is equivalent to the C code of:
*(char*)str = '\0'; // assuming that str points to a valid memory address
Conditional statements and loops are represented through jumps
in assembly.
They work by jumping to a label
that is somewhere else in the program:
...
jmp .LABEL
mov rax, 0 ; <------- this line of code will never be executed
.LABEL:
...
If
statements are achived by comparing registers and using conditional jumps:
...
test rax, rax ; test the value in rax
jz .LABEL ; jump to LABEL if the value in rax is zero
mov rax, 0 ; set rax to zero if it wasn't before
.LABEL:
...
Loops
are achived by comparing registers and using conditional jumps to jump back in the program flow:
mov rdx, 10
mov rcx, 0
.LOOP:
add rcx, 1 ; add one to rcx
cmp rcx, rdx ; compare the value in rcx to rdx
jl .LOOP ; jump back to .LOOP while the value in rcx < rdx
- hands down the best reference for this project
- wikipedia on x86_64
- wikipedia on x86_64 System V AMD64 ABI calling convention
- how to transform assembly code into an executable
- nasm cheat sheet
- official nasm documentation
- what are syscalls (long read but very informative)
- system call table for x86_64
- all x86_64 instructions out there