Angenommen, Sie haben eine Nummer:0x1006
Aus bestimmten Gründen möchten Sie es an einem 4 ausrichten Byte-Grenze.
Bei einer 4-Byte-Grenze wissen Sie, dass ausgerichtete Werte 0x1000 sind , 0x1004 , 0x1008 , usw. Sie kennen dann auch den ausgerichteten Wert von 0x1006 ist 0x1008 .
Wie würden Sie 0x1008 bekommen ? Die Ausrichtungsmaske für den Ausrichtungswert 4 ist (4 - 1) = 0x03
Jetzt 0x1006 + 0x03 = 0x1009 und 0x1009 & ~0x03 = 0x1008
Diese Operation ist der __ALIGN_MASK Makro.
Wenn Sie den Wert 4 übergeben möchten (die Ausrichtung) statt direkt 0x03 (die Ausrichtungsmaske), haben Sie die ALIGN Makro
#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1)
die Ausrichtung, a , wird in x umgewandelt 's Typ, und dann wird eins subtrahiert. Die Ausrichtung sollte eine Potenz von 2 sein, so dass sich eine Zahl des Bitmusters 00..011..11 ergibt von x 's Typ, die Maske (k 1s wenn a = 2^k ).
Dann
#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
fügt den Wert der Maske zu x hinzu , sodass (x)+ (mask) ist mindestens so groß wie das kleinste Vielfache der Ausrichtung, das nicht kleiner als x ist und kleiner als das nächstgrößere Vielfache. Dann wird diese Zahl bitweise und mit dem Komplement der Maske auf das Vielfache der Ausrichtung reduziert.
Für Masken der Form 2^k - 1 , die Berechnung
(x + mask) & ~mask
ist dasselbe wie
(x + 2^k - 1) - ((x + 2^k - 1) % (2^k))
oder
((x + 2^k - 1)/(2^k)) * (2^k)