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).
}
