Nesse laboratório vamos explorar a interface com o sistema operacional.
Para começar, pegue o
programa em C, que copia o arquivo dado na linha
de comando para a saída padrão (tela), e
salve-o em um arquivo copia.c
.
Compile e execute esse programa, testando-o com algum
arquivos de entrada:
> gcc -Wall -o copia copia.c
> ./copia arquivodeentrada
copia.c
.
A rotina main
chama quatro funções definidas neste
mesmo arquivo: myopen
, myread
, mywrite
e myclose
.
Cada uma dessas funções é implementada por uma única linha, que
contém uma chamada ao sistema operacional (na verdade, uma
chamada a uma função wrapper, provida pela biblioteca padrão de C).
As chamadas ao sistema operacional são documentadas na seção 2 do manual
do Linux.
Para ver a documentação de uma delas, basta escrever, por exemplo:
> man 2 open
myopen
, myread
, mywrite
e myclose
).
por equivalentes a elas escritas em assembly.
Atenção: suas funções assembly não devem chamar as funções da biblioteca de C! Elas devem usar traps para interfacear diretamente com o SO.
Crie um arquivo chamadas.s
,
e comece substituindo a função myopen
.
Comente a definição (não o protótipo!) dessa função
no arquivo copia.c
e declare-a
como pública (globl
) em chamadas.s
.
Implemente myopen
em assembly (ver instruções abaixo), e compile tudo agora com:
> gcc -Wall -m32 chamadas.s copia.c
Para descobrir o código das chamadas ao sistema, consulte
a tabela
de chamadas ou
o arquivo "/usr/include/asm/unistd.h"
Observe os seguinte pontos:
int $0x80
copia.c
e substituindo-as pela
implementação em assembly em chamadas.s
.
A implementação em assembly de chamadas a serviços do sistema
operacional que você acabou de fazer é
semelhante à implementação das funções wrapper
disponíveis na biblioteca padrão de C.