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.