In C, I have a 32-bit word representing an address (and I have it stored in an unsigned long, hope that's ok). Now from what I gather, part of an address contains the page number and the other part contains the offset. I was wondering how I could extract just the bits that give me the page number. I have already worked out the first 22 most significant bits are the page number and the other 10 bits are the page offset. How can I grab just the bits that are the page number? I am thinking I can do this with some bitwise operations, but am not sure how.
The Extract Bits block allows you to output a contiguous selection of bits from the stored integer value of the input signal. Use the Bits to extract parameter to define the method for selecting the output bits.
The Extract Bits block allows you to output a contiguous selection of bits from the stored integer value of the input signal. Use the Bits to extract parameter to define the method for selecting the output bits. Select Upper half to output the half of the input bits that contain the most significant bit.
If you select Upper half for the Bits to extract parameter, the output is 11011 in binary. If you select Lower half for the Bits to extract parameter, the output is 11001 in binary.
Contiguous selection of extracted bits, specified as a scalar, vector, matrix, or N-D array. Floating-point inputs are passed through the block unchanged. Select the method for extracting bits from the input signal. If you select Upper half for the Bits to extract parameter, the output is 11011 in binary.
Use the bitshift operators to extract the bits you need.
pageNumber = x >> 10;
offset = x & ((1 << 10) - 1);
For the page number, the >> operator shifts bits down, so you lose the least signifcant bits.
For the offset, ((1 << 10) - 1) creates a bitmask consisting of 10 ones which is used to select only the 10 least significant bits and ignore the most significant bits.
I'm a huge fan of the "two shifts" method of field extraction. It works both signed and unsigned. To extract a field of width w
with least significant bit lsb
from word
:
#define BITSIN(W) (8*sizeof(W))
return (word << (BITSIN(word) - (lsb+width))) >> (BITSIN(word) - width);
In this case, BITSIN(word) == 32
and lsb+width == 32
, so as long as the word in question is unsigned, you can just shift right 10 without masking.
One caution: beware 32-bit shifts on 32-bit types! The C standard lets the compiler do anything, and what the common Intel chips do is not useful: x << y
shifts x
left by y % 32
bits (provided x
has a 32-bit integer type). This means if you try to shift a 32-bit integer left or right by 32 bits, the result is the same as a no-op. There is a similar issue with 64-bit shifts of 64-bit types.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With