Mi trovo ancora negli oscuri anfratti di linux, voglio capire come viene terminato un processo e come restituisce il controllo all'os. Io ho sempre saputo, che a questo scopo si dovrebbe chiamare l'interruzione software "int 0x80" fornendoli come parametro $1 tramite il registro %eax.
Ma quando disassemblo questo codice, linkato staticamente:
codice:
#include<stdlib.h>
void main()
{
exit(0);
}
codice:
(gdb) disas main
Dump of assembler code for function main:
0x00000000004004d4 <+0>: push %rbp
0x00000000004004d5 <+1>: mov %rsp,%rbp
0x00000000004004d8 <+4>: mov $0x0,%edi
0x00000000004004dd <+9>: callq 0x4010b0 <exit>
End of assembler dump.
dopodiché "(gdb) disassemble exit" mi restituisce un listato bello lungo che non ho esaminato per intero, ma al suo interno vi sono 3 call a subroutine diverse: __exit_funcs, _exit, free.
Approfondisco la sub _exit:
codice:
(gdb) disas _exit
Dump of assembler code for function _exit:
0x000000000040d900 <+0>: movslq %edi,%rdx
0x000000000040d903 <+3>: mov $0xffffffffffffffb0,%r9
0x000000000040d90a <+10>: mov $0xe7,%r8d
0x000000000040d910 <+16>: mov $0x3c,%esi
0x000000000040d915 <+21>: jmp 0x40d930 <_exit+48>
0x000000000040d917 <+23>: nopw 0x0(%rax,%rax,1)
0x000000000040d920 <+32>: mov %rdx,%rdi
0x000000000040d923 <+35>: mov %esi,%eax
0x000000000040d925 <+37>: syscall
0x000000000040d927 <+39>: cmp $0xfffffffffffff000,%rax
0x000000000040d92d <+45>: ja 0x40d948 <_exit+72>
0x000000000040d92f <+47>: hlt
0x000000000040d930 <+48>: mov %rdx,%rdi
0x000000000040d933 <+51>: mov %r8d,%eax
0x000000000040d936 <+54>: syscall
0x000000000040d938 <+56>: cmp $0xfffffffffffff000,%rax
0x000000000040d93e <+62>: jbe 0x40d920 <_exit+32>
0x000000000040d940 <+64>: neg %eax
0x000000000040d942 <+66>: mov %eax,%fs:(%r9)
0x000000000040d946 <+70>: jmp 0x40d920 <_exit+32>
0x000000000040d948 <+72>: neg %eax
0x000000000040d94a <+74>: mov %eax,%fs:(%r9)
0x000000000040d94e <+78>: jmp 0x40d92f <_exit+47>
End of assembler dump.
A questo punto, si inizia a vedere aria di uscita! Ho pensato che syscall faccia le veci di int 0x80, ma che parametri passargli per restituire il controllo al sistema? Nel listato di _exit viene chiamata in due modi diversi: prima con $0xe7 in %aex, nella chiamata <_exit+54>; poi in funzione della comparazione in <_exit+56>, viene caricato il valore $0x3c oppure il suo complementare in %aex per poi eseguire syscall.
Sono sulla retta via o completamente fuori strada, mi pongo il dubbio perché tutte guide a riguardo mostrano codice molto più semplice, rispetto ai castelli di software che ho trovato? Inoltre dove posso trovare un quadro delle azioni di syscall in base ai parametri?