A relatively trivial question today
Suppose I have a the following code:
int extract_bits_21_to_25(unsigned char* instruction) {
int instruction_to_int = *(int*)instruction;
int bits_21_to_25 = (instruction_to_int >> 20) & 0x1F;
return bits_21_to_25;
}
unsigned char* reverse(unsigned char* instruction){
int length = strlen(instruction);
for (int i = 0; i < length / 2; i++) {
char temp = instruction[i];
instruction[i] = instruction[length - i - 1];
instruction[length - i - 1] = temp;
}
return instruction;
}
int main(int argc, char *argv[]) {
unsigned char dummy_instruction[4] = {0x13,0x01,0xF0,0x7F};
unsigned char* big_endian = reverse(dummy_instruction);
int instruction_to_int = *(int*)big_endian;
int bits_21_to_25 = (instruction_to_int >> 21) & 0xFF;
printf("%d",bits_21_to_25);
return 0;
}
When I convert the instruction to big endian I get 0x7F, 0xF0, 0x01, 0x13
Now this in binary is: 01111111 11110000 00000001 00010011
I wish to extract bits 21 to 25 which is 00010, I also wish to convert this to a integer, which is 2
How do I go about doing this My code above does not work for some reason.
A safe way to read integers from character array is taking each bytes in a loop.
unsigned int read_4byte(const unsigned char* data) {
unsigned int ret = 0;
// for (int i = 0; i < 4; i++) { // for big endian
for (int i = 3; i >= 0; i--) { // for little endian
ret = (ret << 8) | data[i];
}
return ret;
}
Your "bits 21 to 25" looks like actually bt 7 to 11 (counted from LSB, 0-origin).
You can use this function to extract bits in your counting (counted from MSB, 1-origin).
unsigned int get_bits(unsigned int source, int from, int to) {
int length = to - from + 1;
int bit_offset = 32 - to;
unsigned int mask = length == 0 ? 0 : (((1u << (length - 1)) - 1) << 1) | 1;
return (source >> bit_offset) & mask;
}
Usage example:
unsigned int instruction_to_int = read_4byte(dummy_instruction);
int bits_21_to_25 = get_bits(instruction_to_int, 21, 25);