Řekněme, že máte číslo:0x1006
Z některých důvodů jej chcete zarovnat na 4 hranice bajtů.
Se 4bajtovou hranicí víte, že zarovnané hodnoty jsou 0x1000 , 0x1004 , 0x1008 , atd. Pak také znáte zarovnanou hodnotu 0x1006 je 0x1008 .
Jak byste získali 0x1008 ? Maska zarovnání pro hodnotu zarovnání 4 je (4 - 1) = 0x03
Nyní 0x1006 + 0x03 = 0x1009 a 0x1009 & ~0x03 = 0x1008
Tato operace je __ALIGN_MASK makro.
Pokud chcete předat hodnotu 4 (zarovnání) místo přímo 0x03 (maska zarovnání), máte ALIGN makro
#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1)
zarovnání, a , je přetypován na x 's type a pak se jedna odečte. Zarovnání by mělo být mocninou 2, takže výsledkem bude číslo bitového vzoru 00..011..11 z x 's type, maska (k 1s if a = 2^k ).
Potom
#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
přidá hodnotu masky na x , takže (x)+ (mask) je alespoň tak velký jako nejmenší násobek zarovnání, který není menší než x a menší než nejbližší větší násobek. Poté bitové a s doplňkem masky sníží toto číslo na tento násobek zarovnání.
Pro masky ve tvaru 2^k - 1 , výpočet
(x + mask) & ~mask
je stejný jako
(x + 2^k - 1) - ((x + 2^k - 1) % (2^k))
nebo
((x + 2^k - 1)/(2^k)) * (2^k)