Assemblage - Appels système

Les appels système sont des API pour l'interface entre l'espace utilisateur et l'espace noyau. Nous avons déjà utilisé les appels système. sys_write et sys_exit, respectivement pour écrire dans l'écran et quitter le programme.

Appels système Linux

Vous pouvez utiliser les appels système Linux dans vos programmes d'assemblage. Vous devez suivre les étapes suivantes pour utiliser les appels système Linux dans votre programme -

  • Mettez le numéro d'appel système dans le registre EAX.
  • Stockez les arguments de l'appel système dans les registres EBX, ECX, etc.
  • Appelez l'interruption correspondante (80h).
  • Le résultat est généralement renvoyé dans le registre EAX.

Il existe six registres qui stockent les arguments de l'appel système utilisé. Ce sont les EBX, ECX, EDX, ESI, EDI et EBP. Ces registres prennent les arguments consécutifs, en commençant par le registre EBX. S'il y a plus de six arguments, alors l'emplacement mémoire du premier argument est stocké dans le registre EBX.

L'extrait de code suivant montre l'utilisation de l'appel système sys_exit -

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

L'extrait de code suivant montre l'utilisation de l'appel système 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

Tous les appels système sont répertoriés dans /usr/include/asm/unistd.h , avec leurs numéros (la valeur à mettre dans EAX avant d'appeler int 80h).

Le tableau suivant présente certains des appels système utilisés dans ce didacticiel -

% eax Nom % ebx % ecx % edx % esx % edi
1 sys_exit int - - - -
2 sys_fork struct pt_regs - - - -
3 sys_read entier non signé char * size_t - -
4 sys_write entier non signé const char * size_t - -
5 sys_open const char * int int - -
6 sys_close entier non signé - - - -

Exemple

L'exemple suivant lit un nombre sur le clavier et l'affiche à l'écran -

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

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -

Please enter a number:
1234  
You have entered:1234