Programar em Assembly com GAS/Linux System Call

Linux system call

editar

System call (chamadas ao sistema do núcleo) e um mecanismo utilizado por programas por meio dais interrupções para fazer chamadas ao sistema operacional.
No Linux as tabela system call e definida dentro do arquivo "arch/i386/kernel/entry.S".
Para fazer chamadas ao sistema cada sistema operacional tem a sua prorpia interrupção.
No kernel Linux as chamada são feitas por meio da interrupção 0x80 .

################################ teste.s ##############################
# Escrever um comentario
#
# Para compilara
# as teste.s -o teste
# ld teste.o -o teste 
#
.text
.section .data
    .equ  SYS_WRITE, 4
    .equ  LINUX_SYSCALL , 0x80
#                                       
.global _start
 _start:
      movl     $len,%edx
      movl     $msg,%ecx
      movl     $1,%ebx
      movl     $SYS_WRITE,%eax
      int      $LINUX_SYSCALL
      movl     $0,%ebx
      movl     $1,%eax
      int      $LINUX_SYSCALL  
.data                                   
 msg:
.ascii "Oi MUNDO finalmente VIVO!!!\n" 
 len = . - msg
#De um enter no fim do código antes de registrar "evitar erros" 

Com o "AS" utilizamos "$" para definir operadores.

Aqui nos usamos a interrupção "write" do system call Linux.
Mais temos varias outras o Linux tem 319 interrupções diferentes.
A interrupção "write" e para "C" mais toda função do system call e representada por um numero para poder ser utilizada em assembly.
E uma regra que nao muda todo numero de interrupção para Linux deve ser colocada dentro do registrador %eax.

%eax Nome Codigo %ebx %ecx
4 sys_write fs/read_write.c unsigned int const char *


Vemos que "%ebx" e um "unsigned int".
Vamos mover "1" que vai dizer para o kernel para mostrar a mensagem no terminal.

  • 1 stdout - saída standard para o terminal.

E em "const char*" que em assembly esta representado como "%ecx" colocamos os nossos caracteres. E para mandar todas estas informações para o kernel usamos a interrupção "int 0x80".

Agora vamos ver a interrupção "sys_exit".

%eax Nome Codigo %ebx
1 sys_exit kernel/exit.c int

Movemos "1" em "%eax" e movemos "0" em "%ebx".
E mandamos as informações com int 0x80.
Podemos remarcar que na linguagem "C" é igual a a exit(0).