Invoking a System call via Assembly | Cerca per titolo, autore, parola chiave | ||||||||
Invoking a System call via Assembly Shashank Jain, Nov 11, 2018. Oggi, proveremo a scrivere una system call (chiamata di funzione), utilizzando puro codice Assembly. Ricordiamo: una system call permette ad un'applicazione utente di interloquire con il kernel. Il meccanismo di protezione offerto da Linux, infatti, non permette ad un programma utente di invocare direttamente il kernel, ma prevede una qualche collaborazione hardware, utilizzando gli interrupt software, per passare dallo spazio utente allo spazio kernel. Per invocare una system call, i registri CPU coinvolti sono: RAX — contiene il numero della system call da invocare. Ad ogni system call, infatti, il kernel associa un numero predefinito e stabile, il cui elenco si trova nel file: /usr/include/x86_64-linux-gnu/asm/unistd_64.h RDI — contiene il valore del primo argomento richiesto dalla funzione invocata. La tabella delle syscall e i prototipi di tutte le funzioni sono contenute in un file del tipo: /usr/src/linux-headers-x.xy.y-64/include/linux/syscalls.h a seconda della distribuzione Linux in uso. RSI — contiene il valore del secondo argomento richiesto dalla funzione invocata. RDX — contiene il valore del terzo argomento richiesto dalla funzione invocata. R10 - contiene il valore del quarto argomento richiesto dalla funzione invocata. R8 - contiene il valore del quinto argomento richiesto dalla funzione invocata. R9 – contiene il valore del sesto argomento richiesto dalla funzione invocata. Proviamo a scrivere un semplice programma che stampi il solito messaggio, Hello world!, sullo schermo. Per farlo, dovremo invocare la system call WRITE: ssize_t write(int fd, const void *buf, size_t count) che chiede, come primo argomento, il file descriptor di destinazione: il file descriptor per lo stdin è 0, per lo stdout è 1, perl lo stderr è 2. Visto che vogliamo stampare il messaggio a terminale, STDOUT, il file descriptor da inserire nel registro RDI è 1. Il secondo argomento richiesto, da mettere nel registro RSI, è la locazione di memoria di inizio del buffer contenente il messaggio da stampare. Il terzo argomento richiesto è la lunghezza del messaggio da stampare (Hello world!, 13 caratteri, compreso il Line Feed finale), da inserire nel registro RDX. Il registro RAX, invece, conterrà 1, che è il numero corrispondente alla SYS CALL WRITE. Quindi, il codice assembly da utilizzare sarà: section .data msg db "Hello world!",10 section .text global _start _start: mov rax, 1 mov rdi, 1 mov rsi, msg mov rdx, 13 syscall mov rax, 60 mov rdi, 0 syscall syscall è l'istruzione che invia un interrupt alla CPU, per dirle di interrompere il processo in esecuzione, per eseguire quest'ultimo pezzo di codice. Nelle ultime due righe, il codice esegue un'altra SYS_CALL: EXIT, che corrisponde al numero 60 e chiede un solo parametro, da inserire nel registro RDI: il codice di uscita (zero, in questo caso, per segnalare il successo della chiusura).
|
|||||||||
Invoking a System call via Assembly | Disclaimer: questo è un link a contenuti ospitati su server esterni. |