2016-10-24 5 views
1

Eh bien, j'ai trouvé quelque chose qui me intéresse et je ne sont pas parvenus à trouver une réponse pour elle ....arguements variadique et x64

comment le va_arg \ va_start \ va_list \ va_end macros fonctionnent sous le capot en x64? appeler convention dans i386 transmet les paramètres sur la pile d'où la macro incrémente juste un pointeur qui pointe vers la base de la pile et le transmet mais en x64 tous les paramètres sont passés par des registres .... alors que se passe-t-il? comment la fonction appelée sait-elle quels registres ont été utilisés pour passer des arguments et ne les écrase pas ...

+0

Certains (nombreux?) Compilateurs _might_ transmettent des arguments dans des registres en mode x64, mais ce ne sera pas une différence inhérente entre x86 et x64, c'est leur choix. De plus, ils ne peuvent pas toujours passer tous les arguments dans les registres (une fonction avec 100 paramètres?). Le 'va_list' pourrait contenir des détails sur le nombre d'arguments passés dans les registres, et sur celui auquel il appartient, mais mon _guess_ indique que les paramètres variadiques sont simplement passés dans la pile dans tous les cas. – TripeHound

+1

[Ce blog] (https://blog.nelhage.com/2010/10/amd64-and-va_arg/) le décrit – samgak

+1

@TripeHound Ce n'est pas à la hauteur du compilateur. Pourquoi les gens croient-ils ce mythe et le propagent-ils? Alors qu'un compilateur peut faire ce qu'il veut, un compilateur comme celui-ci serait sans valeur. Un compilateur cible une architecture avec un ABI assez bien défini. Et les ABI x64 actuellement existants spécifient tous deux des registres pour transmettre des arguments de fonction. Même pour les fonctions variées (pas de différence entre celles-ci et les fonctions normales). – Art

Répondre

1

Ceci est défini par l'ABI pour l'architecture. Sur le SysV ABI pour AMD64 (tout pour à peu près autre que Windows), le ABI document dit (page 56 et avant):

Le prologue d'une fonction qui prend une liste d'arguments variable et connue pour appeler le va_start macro est devrait enregistrer les registres d'arguments dans la zone de sauvegarde du registre.

Alors va_list est un struct avec un pointeur sur le registre zone de sauvegarde et de la place sur la pile où certains arguments supplémentaires auraient pu être passé (pas tous les arguments de fonction d'ajustement dans les registres).

+0

cela signifie que cela nécessite le support du compilateur et que toutes les fonctions variadiques doivent sauvegarder tous les registres sur la pile. – DrPrItay

+0

@DrPrItay: L'ABI spécifie quels registres peuvent être utilisés pour quoi. Seuls 6 des 16 regs d'entiers sont utilisés pour arg-passing (dans la convention d'appel SysV), alors que les autres registres peuvent toujours être interceptés par des appels de fonction. –