3 ms·
Here's a little gem that I don't see mentioned on there. For bit unpacking in C, the natural inclination is to shift out the least significant bit with somethi
by psykotic 11y ago
Here's a little gem that I don't see mentioned on there.
For bit unpacking in C, the natural inclination is to shift out the least significant bit with something like this:
u1 getbit() { u1 lsb = x & 1; x >>= 1; return lsb; }
However, most assembly languages have a better alternative if you instead shift out the most significant bit. Suppose that the bit buffer is in ECX. Then you would do ADD ECX, ECX to left shift ECX and (this is the important part) put the shifted-out bit into the carry flag. From there the carry flag can be shifted into the least significant bit of another register, say EAX, with ADC EAX, EAX, or you can branch based on the carry with JC/JNC
As a full example, here is the gamma decoder from apack/aplib, which despite its simplicity rewards careful study:
getbit:
add dl, dl
jnz .stillbitsleft
mov dl, [esi]
inc esi
adc dl, dl
.stillbitsleft:
ret
getgamma:
xor ecx, ecx
getgamma_no_ecx:
inc ecx
.getgammaloop:
call getbit
adc ecx, ecx
call getbit
jc .getgammaloop
ret