Reading the assembly source code for strcpy in glibc, I found an interesting and efficient way to check if a multi-byte register contains a null byte. This document explains how it works.
Let , , and be 64-bit registers. Suppose that we want to check if at least one among the eight bytes in is zero. We set to a magic number and store the sum of and in .
Suppose that each of the eight bytes in is nonzero. In calculating the sum of and , the zeroth byte apparently has a carry to the first byte. The second byte of plus the carry yields , so that the first byte has a carry to the second. We can analogously verify each of the zeroth through sixth bytes has a carry to the text byte of it. For the same reason, the seventh byte sets the carry flag (CF).
On the other hand, if one byte among the eight bytes in is zero, calculation of does not yield a carry from the particular byte to the next, even if there is a carry from the previous byte. This means that has no null byte if and only if every byte has a carry to the next (or CF) in calculation of .
While it is easy to check if CF is set, how can we check if each of the first through seventh bytes gets a carry in calculation of ? Note that the last significant bit of is zero. Thus, a byte has a carry from the previous one if and only if the least significant bit of the byte is flipped in the addition. We thus calculate the bitwise XOR of and and store the result in : Also, note that masks in all bits in a byte but the least significant one. Let’s take the bitwise OR of and and store the result in : After this operation, the register contains a null byte if and only if all bits of are ones. An easy way to check the latter condition is to test if addition of one to yields zero. If is zero, contains no null byte; otherwise has at least one null byte.
Although the current discussion assumed , , and are 64-bit registers, the technique described above naturally extends to multibyte registers of any size.