Assembly - Chiamate di sistema

Le chiamate di sistema sono API per l'interfaccia tra lo spazio utente e lo spazio kernel. Abbiamo già utilizzato le chiamate di sistema. sys_write e sys_exit, rispettivamente per scrivere sullo schermo e uscire dal programma.

Chiamate di sistema Linux

È possibile utilizzare le chiamate di sistema Linux nei programmi assembly. È necessario eseguire i seguenti passaggi per utilizzare le chiamate di sistema Linux nel programma:

  • Metti il ​​numero di chiamata di sistema nel registro EAX.
  • Memorizza gli argomenti della chiamata di sistema nei registri EBX, ECX, ecc.
  • Chiama il relativo interrupt (80h).
  • Il risultato viene solitamente restituito nel registro EAX.

Ci sono sei registri che memorizzano gli argomenti della chiamata di sistema utilizzata. Questi sono EBX, ECX, EDX, ESI, EDI e EBP. Questi registri accettano gli argomenti consecutivi, a partire dal registro EBX. Se sono presenti più di sei argomenti, la posizione di memoria del primo argomento viene memorizzata nel registro EBX.

Il seguente frammento di codice mostra l'uso della chiamata di sistema sys_exit -

mov	eax,1		; system call number (sys_exit)
int	0x80		; call kernel

Il seguente frammento di codice mostra l'uso della chiamata di sistema sys_write -

mov	edx,4		; message length
mov	ecx,msg		; message to write
mov	ebx,1		; file descriptor (stdout)
mov	eax,4		; system call number (sys_write)
int	0x80		; call kernel

Tutte le chiamate di sistema sono elencate in /usr/include/asm/unistd.h , insieme ai loro numeri (il valore da inserire in EAX prima di chiamare int 80h).

La tabella seguente mostra alcune delle chiamate di sistema utilizzate in questo tutorial:

% eax Nome % ebx % ecx % edx % esx % edi
1 sys_exit int - - - -
2 sys_fork struct pt_regs - - - -
3 sys_read unsigned int char * size_t - -
4 sys_write unsigned int const char * size_t - -
5 sys_open const char * int int - -
6 sys_close unsigned int - - - -

Esempio

L'esempio seguente legge un numero dalla tastiera e lo visualizza sullo schermo:

section .data                           ;Data segment
   userMsg db 'Please enter a number: ' ;Ask the user to enter a number
   lenUserMsg equ $-userMsg             ;The length of the message
   dispMsg db 'You have entered: '
   lenDispMsg equ $-dispMsg                 

section .bss           ;Uninitialized data
   num resb 5
	
section .text          ;Code Segment
   global _start
	
_start:                ;User prompt
   mov eax, 4
   mov ebx, 1
   mov ecx, userMsg
   mov edx, lenUserMsg
   int 80h

   ;Read and store the user input
   mov eax, 3
   mov ebx, 2
   mov ecx, num  
   mov edx, 5          ;5 bytes (numeric, 1 for sign) of that information
   int 80h
	
   ;Output the message 'The entered number is: '
   mov eax, 4
   mov ebx, 1
   mov ecx, dispMsg
   mov edx, lenDispMsg
   int 80h  

   ;Output the number entered
   mov eax, 4
   mov ebx, 1
   mov ecx, num
   mov edx, 5
   int 80h  
    
   ; Exit code
   mov eax, 1
   mov ebx, 0
   int 80h

Quando il codice precedente viene compilato ed eseguito, produce il seguente risultato:

Please enter a number:
1234  
You have entered:1234