Ensamblado - Llamadas al sistema

Las llamadas al sistema son API para la interfaz entre el espacio de usuario y el espacio del kernel. Ya hemos utilizado las llamadas al sistema. sys_write y sys_exit, para escribir en la pantalla y salir del programa, respectivamente.

Llamadas al sistema Linux

Puede hacer uso de las llamadas al sistema Linux en sus programas ensambladores. Debe seguir los siguientes pasos para usar las llamadas al sistema Linux en su programa:

  • Ponga el número de llamada del sistema en el registro EAX.
  • Almacene los argumentos de la llamada al sistema en los registros EBX, ECX, etc.
  • Llame a la interrupción correspondiente (80h).
  • El resultado generalmente se devuelve en el registro EAX.

Hay seis registros que almacenan los argumentos de la llamada al sistema utilizada. Estos son EBX, ECX, EDX, ESI, EDI y EBP. Estos registros toman los argumentos consecutivos, comenzando con el registro EBX. Si hay más de seis argumentos, entonces la ubicación de memoria del primer argumento se almacena en el registro EBX.

El siguiente fragmento de código muestra el uso de la llamada al sistema sys_exit -

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

El siguiente fragmento de código muestra el uso de la llamada al 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

Todas las llamadas al sistema se enumeran en /usr/include/asm/unistd.h , junto con sus números (el valor para poner en EAX antes de llamar a int 80h).

La siguiente tabla muestra algunas de las llamadas al sistema utilizadas en este tutorial:

% eax Nombre % ebx % ecx % edx % esx % edi
1 sys_exit En t - - - -
2 sys_fork struct pt_regs - - - -
3 sys_read int sin firmar char * size_t - -
4 sys_write int sin firmar const char * size_t - -
5 sys_open const char * En t En t - -
6 sys_close int sin firmar - - - -

Ejemplo

El siguiente ejemplo lee un número del teclado y lo muestra en la pantalla:

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

Cuando se compila y ejecuta el código anterior, produce el siguiente resultado:

Please enter a number:
1234  
You have entered:1234