Alignement d’un pointeur de stack de 8 octets sur 4 octets dans un assemblage ARM

Comment aligner un pointeur de stack sur 8 octets, qui est maintenant aligné sur 4 octets dans ARM

Ainsi, l’alignement d’un pointeur de stack sur 8 octets signifie qu’il doit pointer vers des adresses telles que 0x8, 0x16, 0x24 et 0x32, etc.

Maintenant, comment puis-je aligner le pointeur de stack de 4 octets sur le pointeur aligné de 8 octets?

En raison de la stack décroissante

bic sp, sp, #7 

devrait suffire. Avec EABI, vous pouvez utiliser r12 ou r0-r3 pour (ré) mémoriser la valeur précédente.

Tout cela ne devrait être fait qu’en assemblée; en C, vous pouvez compter sur un pointeur de stack correctement aligné et essayer de le modifier entraînera probablement le blocage de votre programme.

Les compilateurs veillent à l’alignement correct; des stacks mal alignées peuvent survenir lors d’appels interrompus. Certaines CPU (par exemple Cortex-M3) ont des registres spéciaux (STKALIGN) qui peuvent être utilisés pour entrer des irq avec un alignement de stack à 8 bits.

N’essayez pas d’aligner manuellement sp vous-même, mais push un autre registre pour obtenir l’alignement. Par exemple au lieu de

 push {r3, r4, lr} 

ajoutez un autre registre à la liste pour obtenir facilement l’alignement sur 8.

 push {r1, r3, r4, lr} 

Cela peut sembler être un access supplémentaire à la mémoire, mais en général, les caches fonctionnent avec des vecteurs de bits plus larges que les tailles de mots natives.

Une autre remarque est également, vous n’avez pas besoin de vous forcer à aligner correctement la stack si vous ne faites pas d’appels externes ou ne recevez pas. Ainsi, si vous avez une routine d’assemblage de boîtes fermées qui n’appelle pas le monde externe ni n’en reçoit, vous pouvez vivre avec un alignement de stack cassé tant que cela ne vous empêche pas de charger vous-même.

Pour déplacer un pointeur jusqu’à la limite de 8 octets la plus proche, sans le modifier, s’il s’agit déjà d’un multiple de 8 (pseudo-code – vous devrez append des conversions si vous le faites en C):

 p = (p + 7) & ~7; 

ou de la même manière pour le réduire à la limite de 8 octets la plus proche:

 p = p & ~7; 

Si vous écrivez des fonctions feuille (pas d’appel de sous-routine), ne vous embêtez pas.

Vous êtes parfaitement à l’aise avec un SP aligné sur 4 octets car cette exigence est due aux instructions ldrd et strd qui nécessitent que l’adresse soit un multiple de huit. Par conséquent, si la fonction que vous écrivez n’appelle aucun sous-programme que vous ne connaissez pas, cela n’est pas nécessaire. (ldrd et strd sont si rarement utilisés de toute façon)

Le SP est déjà aligné sur 8 octets lorsque votre fonction est appelée depuis un langage de niveau supérieur.

Si vous souhaitez que le SP soit aligné sur 8 octets, ne le touchez pas ou ne conservez qu’un nombre pair de registres.