long mystrlen(char *s) { // lunghezza di una stringa long len; for (len = 0; *s != 0; len++) s++; return len; } long mywrite(char *s) { //stampa una stringa long addr = (long) s; //addr e' l'indirizzo della stringa long len = mystrlen(s); // e len e' la lunghezza register long r_syscallno asm("rax") = 1; // mette nel registro rax il numero della syscall 1=write // l'elenco completo in /usr/include/x86_64-linux-gnu/asm/unistd_64.h // mutatis mutandis se usare un'altra architetttura di processore register long r_arg1 asm("rdi") = 1; // da "man 2 write" si vede che il 1' paramentro e' il fd. 1 e' stdout register long r_arg2 asm("rsi") = addr; // secondo parametro l'indirizzo del buffer da mettere in output register long r_arg3 asm("rdx") = len; // terzo parametro e' la lunghezza register long r_retvalue asm("rax"); // chiamo r_retvalue il registro rax, dove le syscall mettono il valore di rit. asm("syscall"); // genera la trap per "svegliare" il kernel return r_retvalue; // restituisco il valore di ritorno } void myexit(long value) { // termina il chiamante register long r_syscallno asm("rax") = 60; // la ssytem call 60 e' _exit register long r_arg1 asm("rdi") = value; // ed ha un solo parametro: il valore di ritorno asm("syscall"); } void _start(void) { long retvalue; retvalue = mywrite("hello world\n"); // stampa la famosa stringa myexit(retvalue); // e resituisci come exit status il valore di ritorno della write // e' il numero dei caratteri stampati (o il codice di erroe in negativo). }