( egmont | 2007. 07. 05., cs – 15:28 )

Ezt találtam ki otthon: (C-jellegű szintaxissal, mert Intel assemblyhez nem értek):

long long foo = [a 8 vagy akárhány byte-os cucc];
foo |= (foo >> 1);
foo |= (foo >> 2);
foo |= (foo >> 4);
end_of_string akkor és csak akkor, ha ((foo & 0x0101010101010101) != 0x0101010101010101);

Az első shiftelősdi-vagyolósdi után minden bit azt tartalmazza, hogy az eredeti regiszterben az adott pozíció, és az attól balra lévő pozíció legalább egyikén 1-es bit volt-e.
A második shiftelősdi után immár minden bit 4 kezdeti bitet vagyol össze.
A harmadik shift után pedig minden bit azt mutatja, hogy az ott végződő egymást követő 8 bit között volt-e 1-es kezdetben.
Jelen esetben ebből minden byte-nak a jobb szélső bitje érdekes, a többi szemét. Ha volt 0-s byte (end of string), akkor itt lesz köztük 0-s bit, ellenkező esetben ezek mind 1-es bitek.

Bónusz: C-ben 0x0101... helyett (((unsigned [típus])(-1))/255) fordítási időben épp a megfelelő szóhosszúságban produkálja a szükséges konstanst.

Valszeg elég gyors a fenti algoritmus, mivel nincs benne elágazás, kevés regiszter is elég, és a kód nem lesz hosszabb ahogy nő hogy hány bites architektúrán dolgozol (32 -> 64 -> ki tudja mit hoz a jövő).