Saltar para o conteúdo

Assembly no Linux/Syscalls

Origem: Wikilivros, livros abertos por um mundo aberto.

Syscalls, para quem não está acostumado com o termo, são chamadas de sistema. Uma comparação que podemos fazer é com os serviços do DOS e da BIOS que eram usados quando programados em C ou Assembly. Por exemplo, existia a interrupção do teclado, que era desviada para atualizar um contador e assim manter o relógio do exemplo clássico funcionando. Os serviços, ou interrupções, mais usados eram: 0x21, 0x25, do DOS, e 0x10, 0x16, da BIOS. O princípio era o seguinte, um código de função era carregado em um registro do processador, e parâmetros eram carregados em outros. Em caso de um número excessivo de parâmetros, a função aceitaria um bloco de memória com os parâmetros, em vez de registros.

No caso do Linux, o serviço a ser chamado é o 0x80, que é o gancho para as funções básicas que o kernel nos provê. Vamos nos deter apenas em chamá-la, e não desviá-la, o que em um sistema como este não é tão trivial. Podemos desviar as funções, mas a própria syscall, como fazíamos, é um pouco mais difícil, devido às permissões e exceções do gerenciador de memória, como foi explicado anteriormente, no movo protegido.

Uma lista das funções disponíveis pode ser encontrada no arquivo '/usr/includes/sys/syscall.h ou dentro da fonte do kernel, em caso de uma estrutura diferente de diretórios. Os nomes das chamadas estão no formato SYS_<função>, por exemplo:

SYS_write, SYS_read

Geralmente, a função a ser chamada é carregada em eax, e os argumentos em ebx, ecx, edx, esi, edi, sucessivamente, até cinco argumentos, ou em caso de mais argumentos, um ponteiro para a estrutura com todos é passada por ebx, com todos os argumentos arranjados sucessivamente na memória. O retorno da chamada é dado em eax, que contém o valor de retorno.

O conhecimento das chamadas pode ser obtido lendo as fontes do kernel e também por meio de sites e exemplos disponíveis, mas são todas as funções básicas do sistema, que são explorados por bibliotecas como a GLIBC, que implementa uma série de funções e padrões usados por vários programas.

Temos as RST do Z80 e os hooks da ROM dele, que funcionam com este mesmo princípio. Alguns programas desviam o hook do teclado, para uma rotina que fazia o mesmo que no DOS, atualizando um relógio, ou ainda o hook de Iprint, para fazer filtros para impressoras, que naquela época não seguiam um padrão bem-definido, e vez por outra confundiam os caracteres de nossa língua, o que obrigava a troca de ROMs por aí.

Intencional ou não, este detalhe de projeto sempre abriu muita possibilidade para que os programadores, escassos de recursos e tempos, mas sempre com sobra de imaginação, resolvessem seus problemas. Enquanto certas interrupções são chamadas em um intervalo de tempo regular, outras são chamadas apenas quando da execução de uma determinada função.