I am trying to make a constant round up to the nearest power of 2 in NASM, is this possible?
By constant I mean a symbol that you define using EQU.
I don't want to round constant after it is defined, I want to round it while defining it. The largest power of 2 that I need to be able to round up to is 128. I can't round the constant in assembly because the value of the constant has to be used when I assemble the program.
CodePudding user response:
From Bit Twiddling Hacks, this algorithm rounds a 32-bit unsigned integer to the next power of 2. You can extend it to a larger input range by extending the obvious pattern.
v--;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
v ;
It's simple to translate the code to an NASM macro.
%macro RoundPow2 1
%assign V %1
%assign V V - 1
%assign V V | V >> 1
%assign V V | V >> 2
%assign V V | V >> 4
%assign V V | V >> 8
%assign V V | V >> 16
%assign V V 1
%endmacro
RoundPow2 4
mov eax, V; 4
RoundPow2 6
mov eax, V; 8
RoundPow2 8
mov eax, V; 8
You can, if you want, change the macro to a functional version using