Supponi di avere un numero:0x1006
Per qualche motivo vuoi allinearlo a un 4 limite di byte.
Con un limite di 4 byte, sai che i valori allineati sono 0x1000 , 0x1004 , 0x1008 , ecc. Quindi conosci anche il valore allineato di 0x1006 è 0x1008 .
Come otterresti 0x1008 ? La maschera di allineamento per il valore di allineamento 4 è (4 - 1) = 0x03
Ora 0x1006 + 0x03 = 0x1009 e 0x1009 & ~0x03 = 0x1008
Questa operazione è il __ALIGN_MASK macro.
Se vuoi passare il valore 4 (l'allineamento) invece che direttamente 0x03 (la maschera di allineamento), hai il ALIGN macro
#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1)
l'allineamento, a , viene trasmesso a x 's type, quindi ne viene sottratto uno. L'allineamento dovrebbe essere una potenza di 2, in modo da ottenere un numero del modello di bit 00..011..11 di x , la maschera (k 1s se a = 2^k ).
Allora
#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
aggiunge il valore della maschera a x , in modo che (x)+ (mask) è grande almeno quanto il multiplo più piccolo dell'allineamento che non è minore di x e minore del successivo multiplo maggiore. Quindi il bit per bit e con il complemento della maschera riduce quel numero a quel multiplo dell'allineamento.
Per maschere della forma 2^k - 1 , il calcolo
(x + mask) & ~mask
è uguale a
(x + 2^k - 1) - ((x + 2^k - 1) % (2^k))
o
((x + 2^k - 1)/(2^k)) * (2^k)