2016-10-31 1 views
3

Je suis l'exécution d'un appel système sur OS X (32 bits) comme ceci:Pourquoi les systèmes BSD ont-ils besoin de sous-esp4, lors d'un appel système?

push 123 
mov eax, 1 
sub esp, 4 
int 0x80 

Et je ne comprends pas tout à fait cette lacune sub esp, 4.

J'ai lu quelque part que BSD et ses dérivés ont toujours cet écart, mais n'ont pas pu trouver d'explication pourquoi. J'ai d'abord pensé à l'alignement des piles, mais ce n'est pas le cas, car cette ligne doit être trouvée partout, et autant que je sache, OS X nécessite un alignement de pile de 16 octets (ce qui n'est pas le cas ici non plus).).

Avez-vous une idée de ce qui se cache derrière la nécessité de faire sub esp, 4 ou pourrait me pointer vers des ressources qui le décrivent correctement?

+0

Le raisonnement est discuté ici: https://www.freebsd.org/doc/fr/books/developers-handbook/book.html#x86-system-calls –

+1

C'est parce que vous êtes appelé à appeler une fonction, et c'est l'espace pour l'adresse de retour. Laissez-moi trouver le doublon. – Jester

+0

@MichaelPetch J'ai lu le même document, mais le fait que ce soit un remplacement de 'call' n'explique pas tout à fait pourquoi ce' call' est nécessaire en premier lieu – mewa

Répondre

3

(wiki communautaire parce que je ne fais que résumer les commentaires)

BSD fait cela pour créer des fonctions wrapper libc appels système plus efficace, parce qu'ils ne peuvent tout simplement faire la int 0x80 sans copier args autour. Il laisse place à l'adresse de retour transmise par le CALL à la fonction wrapper.

Il est courant dans le système Unix/Linux que les appels système comme read(2) soient effectivement des fonctions d'encapsulation de librairie autour de l'appel du noyau, plutôt que des macros qui se développent en inline-asm. Linux résout ce problème d'une manière différente: en passant tous les arguments syscall dans les registres. Je suppose que cela signifie que les fonctions wrapper 32 bits doivent charger tous les arguments de la pile, mais au moins ils n'ont pas besoin d'être stockés et relus par le noyau. L'appel système x86-64 ABI est beaucoup plus compatible avec la convention d'appel de fonction: un seul mov r10, rcx est nécessaire, car la convention d'appel de la fonction System V transmet les arguments dans les registres (et les registres syscall sont choisis pour correspondre le plus près possible, sauf the SYSCALL instruction itself destroys RCX and R11, so the kernel can't see the original values.)

Voir le wiki tag pour plus d'informations sur les conventions d'appel et les liens vers les ABI.

+0

Je suis au courant des autres conventions d'appel, j'ai juste besoin de cet espace de 1 pointeur expliqué;) Merci pour les liens en tous cas! – mewa

+1

@mewa: J'espère que certains futurs lecteurs autres que vous en bénéficieront à un moment donné. :) –