J'ajouterai une autre réponse, pour aborder certaines des discussions tangentielles qui ont eu lieu.
L'ABI C (interface binaire d'application) appelait à l'origine à passer des arguments sur la pile dans l'ordre inverse (c'est-à-dire poussé de droite à gauche), où l'appelant libère également le stockage de la pile. L'ABI moderne utilise en fait des registres pour passer des arguments, mais la plupart des considérations de déformation remontent à la transmission d'arguments de la pile d'origine.
L'ABI Pascal original, en revanche, poussait les arguments de gauche à droite, et l'appelé devait faire apparaître les arguments. L'ABI C original est supérieur à l'ABI Pascal original sur deux points importants. L'ordre d'envoi des arguments signifie que le décalage de pile du premier argument est toujours connu, autorisant les fonctions qui ont un nombre inconnu d'arguments, où les premiers arguments contrôlent le nombre d'autres arguments (ala printf
).
La deuxième façon dont l'ABI C est supérieur est le comportement au cas où l'appelant et l'appelé ne s'accordent pas sur le nombre d'arguments. Dans le cas C, tant que vous n'accédez pas réellement aux arguments après le dernier, rien de mal ne se passe. Dans Pascal, le nombre incorrect d'arguments est sorti de la pile et la pile entière est corrompue.
L'ABI Windows 3.1 d'origine était basé sur Pascal. En tant que tel, il a utilisé l'ABI Pascal (arguments dans l'ordre de gauche à droite, l'appelé apparaît). Étant donné que toute non-concordance dans le numéro d'argument peut entraîner une corruption de la pile, un schéma de mutilation a été formé. Chaque nom de fonction a été mutilé avec un nombre indiquant la taille, en octets, de ses arguments. Donc, sur une machine 16 bits, la fonction suivante (syntaxe C):
int function(int a)
A été mutilé function@2
, parce queint
fait deux octets de large. Cela a été fait pour que si la déclaration et la définition ne correspondent pas, l'éditeur de liens ne parviendra pas à trouver la fonction plutôt que de corrompre la pile au moment de l'exécution. Inversement, si le programme est lié, vous pouvez être sûr que le nombre correct d'octets est extrait de la pile à la fin de l'appel.
Windows 32 bits et versions ultérieures utilisent le stdcall
ABI à la place. Il est similaire à l'ABI Pascal, sauf que l'ordre de poussée est comme en C, de droite à gauche. Comme le Pascal ABI, le nom qui modifie la taille en octets des arguments dans le nom de la fonction pour éviter la corruption de la pile.
Contrairement aux revendications faites ailleurs ici, l'ABI C ne modifie pas les noms des fonctions, même sur Visual Studio. Inversement, les fonctions de manipulation décorées avec la stdcall
spécification ABI ne sont pas uniques à VS. GCC prend également en charge cette ABI, même lors de la compilation pour Linux. Ceci est largement utilisé par Wine , qui utilise son propre chargeur pour permettre la liaison au moment de l'exécution des binaires compilés Linux aux DLL compilées Windows.