As chamadas do sistema são armazenadas nos registradores? [fechadas]

0

Eu vi um vídeo no youtube onde as chamadas do sistema estavam presentes para cada registro. Então isso significa que as chamadas do sistema são armazenadas em registros? Se é assim, como isso é possível, quero dizer Eles são acessados pelo kernel que controla o sistema operacional. Então, como um kernel pode acessar os registros e como o kernel sabe qual chamada de sistema está presente em qual registro?

    
por Naren 07.08.2018 / 18:34

1 resposta

4

Não há uma "chamada de sistema ... para cada registro".

A interface de chamada do sistema é dependente da arquitetura de hardware. É frequentemente (quase sempre?) O caso que o processo armazena um número inteiro correspondente à chamada de sistema desejada em um registrador pré-determinado e, em seguida, executa uma instrução que aciona a CPU para transferir a execução para o código de manipulação de chamada do sistema do kernel. O kernel faz referência ao registro pré-determinado para identificar qual sistema de chamada o processo está solicitando e, em seguida, executa o manipulador de chamada de sistema apropriado.

Por exemplo, considere este programa "hello world" no assembly x86_64 para Linux:

$ cat hello.s
        .text
        .global
main:
        movq $1,   %rax # write() system call number
        movq $1,   %rdi # first parameter  -- standard output file descriptor
        movq $msg, %rsi # second parameter -- buffer
        movq $14,  %rdx # third parameter  -- buffer length
        syscall         # invoke system call

        movq $60,  %rax # exit() system call number
        movq $0,   %rdi # first parameter  -- exit status
        syscall         # invoke system call; this will never return

        .section .rodata
msg:
        .ascii "Hello, world!\n"

$ gcc hello.s
$ ./a.out
Hello, world!
$

Para x86_64, o número de chamada do sistema é armazenado no registro rax , o primeiro parâmetro para o sistema todo é armazenado em rdi , o segundo parâmetro para a chamada do sistema é armazenado em rsi e o terceiro parâmetro é armazenado em rdx .

O exemplo começa colocando o valor 1 no registro rax . 1 é o número de chamada do sistema para a chamada do sistema write() . Em seguida, 1 é colocado no registro rdi ; 1 é o descritor de arquivo para saída padrão e rdi é o registrador do primeiro parâmetro. Em seguida, o endereço do msg é armazenado no registro rsi ; rsi é o segundo parâmetro. Em seguida, 14 é armazenado em rdx ; 14 é o comprimento da string e rdx é o registrador do terceiro parâmetro. Em seguida, a instrução syscall aciona a CPU para transferir o controle para o código do kernel. O kernel inspeciona rax , usa o valor naquele registrador (1) para determinar qual chamada de sistema a ser executada (gravação), então invoca o manipulador apropriado.

Quando o kernel termina de executar a chamada do sistema, o controle retorna o processo de espaço do usuário. Escreve 60 para registrar rax ; novamente rax é o registrador do número de chamada do sistema e aqui 60 é o número da chamada do sistema para exit() . Ele escreve 0 para registrar rdi - o primeiro (e único) parâmetro para a chamada do sistema de saída; o status de saída. Novamente, a instrução syscall aciona a CPU para transferir o controle para o código do kernel. O kernel inspeciona rax , usa o valor naquele registrador (60) para determinar qual chamada de sistema para executar (sair) e, em seguida, invoca o manipulador apropriado. O manipulador exit() destrói o processo, de modo que a instrução nunca retorna.

Exemplos que executam a mesma tarefa serão diferentes da arquitetura de hardware para a arquitetura de hardware; não é o mesmo para a Intel de 32 bits.

    
por 07.08.2018 / 19:01