Cela n'a pas l'air d'être pile spécifiques, mais l'alignement en général. Peut-être penser à l'expression multiple entier.
Si vous avez des articles dans une mémoire d'un octet de la taille, des unités de 1, permet de dire qu'ils sont tous alignés. Les choses qui sont de deux octets la taille, puis les entiers de 2 fois sera aligné, 0, 2, 4, 6, 8, etc. Et non des multiples entiers, 1, 3, 5, 7 ne seront pas alignés. Les éléments qui sont de 4 octets la taille, des multiples entiers de 0, 4, 8, 12, etc sont alignés, 1,2,3,5,6,7, etc ne sont pas. En va de même pour 8, 0,8,16,24 et 16 16,32,48,64, et ainsi de suite.
Ce que cela signifie est que vous pouvez rechercher à la base de l'adresse de l'élément et déterminer s'il est aligné.
taille en octets de l'adresse dans le formulaire de
1, xxxxxxx
2, xxxxxx0
4, xxxxx00
8, xxxx000
16,xxx0000
32,xx00000
64,x000000
et ainsi de suite
Dans le cas d'un compilateur de mélange dans les données figurant dans la .segment de texte est assez simple pour aligner les données (eh bien, cela dépend de l'architecture). Mais la pile est un runtime chose, le compilateur ne peut pas normalement de déterminer où la pile sera au moment de l'exécution. Donc, au moment de l'exécution si vous avez des variables locales qui doivent être harmonisées vous auriez besoin d'avoir le code d'ajuster la pile de la programmation.
Disons, par exemple, vous avez deux 8 octets d'éléments sur la pile, un total de 16 octets, et que vous voulez vraiment alignés (sur 8 les limites d'octets). Sur l'entrée de la fonction de soustraction de 16 à partir du pointeur de pile comme d'habitude pour faire de la place pour ces deux éléments. Mais pour les aligner, il faudrait plus de code. Si nous voulions que ces deux 8 octets éléments alignés sur 8 octets limites et le pointeur de pile, après soustraction de 16 a 0xFF82, eh bien, le plus faible de 3 bits ne sont pas à 0 donc il n'est pas aligné. Le bas de trois bits sont 0b010. Dans un sens générique, nous voulons nous soustraire 2 de la 0xFF82 pour obtenir 0xFF80. Comment nous déterminons c'est un 2 serait par anding avec 0b111 (0x7) et en soustrayant de ce montant. Que signifie alu opérations de l'un et de et de soustraction. Mais nous pouvons prendre un raccourci, si nous et avec ceux qui sont le complément de la valeur de 0x7 (~0 x 7 = 0xFFFF...FFF8) nous obtenons 0xFF80 l'aide d'un alu opération (aussi longtemps que le compilateur et le processeur ont une seule opcode façon de le faire, si pas, il peut vous coûter plus de et la et la soustraction).
Cela semble être ce que votre programme est en train de faire. Anding avec -16 est le même que anding avec 0xFFFF....FFF0, résultant en une adresse qui est aligné sur un 16 frontière d'octet.
Donc pour conclure, si vous avez quelque chose comme un typique pointeur de pile qui travaille son chemin vers le bas de la mémoire de la hausse des adresses à la baisse des adresses, vous voulez
sp = sp & (~(n-1))
où n est le nombre d'octets à aligner (doivent être des puissances, mais c'est bien plus l'alignement implique généralement des puissances de deux). Si vous avez dire faire un malloc (adresses augmentation de bas en haut) et à aligner l'adresse de quelque chose (n'oubliez pas de malloc plus que vous avez besoin au moins de l'alignement de la taille) puis
if(ptr&(~(n-)) { ptr = (ptr+n)&(~(n-1)); }
Ou si vous voulez juste prendre le si là-bas et effectuer les opérations d'ajout et de masque à chaque fois.
beaucoup de/la plupart des non-x86 architectures de l'alignement des règles et des exigences. x86 est trop souple en ce qui concerne le jeu d'instruction va, mais pour autant que l'exécution de passe vous pouvez vous/devrez payer une pénalité pour non alignés accède sur un système x86, donc, même si vous pouvez le faire, vous devez vous efforcer de rester alignés, comme vous le feriez avec toute autre architecture. Peut-être est-ce que ce code était en train de faire.