Reading/Writing bits in memory - c

Let's say I'm given a void* memory address and I need to print the bits located in this memory address. How can I do this?
In my processor memory addresses are 32bits as are memory values, also int are 32 bits.
So I thought of doing this:
unsigned int value = *memory_address;
and then by simple arithmetic (some mod and div operations) to get the bits of the value saved in memory_address.
For example value mod 2 will give last bit of this value and so on. But from what I can tell (I was expecting different bits) it doesn't work. Any ideas why?
Also, is anyone aware of ready C source code that "does" such this, reads/writes bits from memory?

Shift the value by one for each bit and or it with 1
unsigned int value = *((unsigned int*)memory_address);
for( int i = 0; i < 32; i++)
{
printf("%d ", value >> i & 1);
}
You can also do it with math operators. You have to get the bit value (2 to the power of the bit index) and substract that value at each iteration to make sure the modulo doesn't return values that we seen before:
for( int i = 0; i < 32; i++)
{
int bit_value = (int)pow(2,i + 1);
int num_bit_value = value % bit_value;
printf("%d ", num_bit_value ? 1 : 0 );
value -= num_bit_value;
}

int main() {
int a = 0xFFFF;
void * v = &a; // v points to a
int * aPtr = (int *) v; // aPtr also points to a
int b = *aPtr; // b gets the value aPtr points to, aka a or 0xFFFF
int aBit = (b >> 3) & 1; // aBit now contains bit 3 of the original a value
// toggle the bit
if (aBit) {
b &= ~(1 << 3); // set bit 3 to 0
} else {
b |= (1 << 3); // set bit 3 to 1
}
*aPtr = b; // update original a
}

I found it easier to think of the memory as a continuous string of characters rather than a void pointer. This way you can address as many bits as you want.
Here is how I have done it.
unsigned char
get_bit(char *array, int bit)
{
int byte, k;
byte = bit/8;
k = 7 - bit % 8;
return array[byte] & (1 << k);
}
void
set_bit(char *array, int bit, unsigned char value)
{
int byte, k;
byte = bit/8;
k = 7 - bit % 8;
if (value)
array[byte] |= (1 << k);
else
array[byte] &= ~(1 << k);
}

How about:
bool isBit4Set = ((*someAddress) & 0x8 != 0);
(*someAddress) |= 0x8; // Set bit 4

Generic solution for printing bytes and bits.
void dump_data(const void *object, size_t size)
{
int i;
printf("[ \n");
for(i = 0; i < size; i++)
{
if (i%4 ==0)
{
printf("#%02X",&((const unsigned char *) object)[i]);
printf("[ ");
}
printf("%02x ", ((const unsigned char *) object)[i] & 0xff);
if ((i+1)%4 == 0)
printf("]\n");
}
printf("]\n");
printf("BINARY FORMAT\n");
for (i = 0; i < size; i++)
{
printf("#%02X",&((const unsigned char *) object)[i]);
printf("[ ");
unsigned char value = (((unsigned char*)object)[i]);
for(int j=0; j<8; j++)
printf("%d ", (value & (0x80 >> j)) ? 1 : 0); // right shifting the value will print bits in reverse.
printf("]\n");
}
}

bool getBit(void* data,int bit){ return ((*((int*)data)) & 1<<bit); }
void setBit(void* data,int bit,bool set){ if(set){ (*((int*)data)) |= 1<<bit; }else{ (*((int*)data)) &= ~(1<<bit); } }
for simple usage

Related

CRC32 - wrong checksum using TABLE algorithm and 04C11DB7 polynomial

I am following a painless guide to code correction algorithms. (https://zlib.net/crc_v3.txt) I've managed to write a TABLE algorithm, using extra loop for augmented part (I hope so). I am trying to write a most widely used CRC32 version (with 0x04C11DB7 polynomial), but I can not get the right CRC value.
I've achieved the correct table for CRC32 values with mentioned polynomial.
My code for generating CRC32 (chapter 9 and 10):
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#define CRC32_BYTE_POSSIBLE_VALUES 255
#define CRC32_LAST_BIT_MASK 0x80000000
#define CRC32_POLYNOMIAL 0x04C11DB7
uint32_t __crc32_table[CRC32_BYTE_POSSIBLE_VALUES] = { 0 };
void __crc32_fill_crc_table() {
uint32_t reg;
uint8_t byte = 0;
for (;;) {
reg = (byte << 24);
for (uint8_t byte_size = 0; byte_size < 8; byte_size++) {
if (reg & CRC32_LAST_BIT_MASK) {
reg <<= 1;
reg ^= CRC32_POLYNOMIAL;
} else {
reg <<= 1;
}
}
__crc32_table[byte] = reg;
if (byte == 255)
break;
else
byte++;
}
}
void __crc32_print_table(uint32_t *arr) {
printf(" 0x%08X ", arr[0]);
for (uint32_t i = 1; i < 256; i++) {
if (!(i % 8))
printf("\n");
printf(" 0x%08X ", arr[i]);
}
printf("\n");
}
uint8_t inverse_byte(uint8_t byte) {
uint8_t reflected_byte = 0;
for (uint8_t i = 0; i < 8; i++) {
if (byte & (1 << i))
reflected_byte |= (1 << (7 - i));
}
return reflected_byte;
}
uint32_t inverse(uint32_t src) {
uint32_t toret;
for (uint8_t i = 0; i < 32; i++) {
if (src & (1 << i))
toret |= (1 << (31 - i));
}
return toret;
}
uint32_t __crc32_table_approach( unsigned char *data, size_t size) {
uint32_t reg = -1;
uint8_t top_byte;
for (size_t i = 0; i < size; i++) {
top_byte = (uint8_t)(reg >> 24);
reg = (reg << 8) | inverse_byte(data[i]);
reg ^= __crc32_table[top_byte];
}
for (size_t i = 0; i < 4; i++) {
top_byte = (uint8_t) (reg >> 24);
reg = (reg << 8) ;
reg ^= __crc32_table[top_byte];
}
return inverse(reg) ^ -1;
}
uint32_t calc_crc32(unsigned char *data, size_t size) {
if (!__crc32_table[1])
__crc32_fill_crc_table();
__crc32_print_table(__crc32_table);
return __crc32_table_approach(data, size);
}
int main( int argc, char** argv )
{
unsigned char* test = "123456789";
size_t test_len = strlen(test);
uint32_t crc = calc_crc32(test, test_len);
printf("CRC32: 0x%08X", crc);
return 0;
}
The inverse function reverses bits of UINT32 value, and function inverse_byte inverses bits of UINT8 value.
But for the '123456789' string I get the wrong checksum.
Could someone help me? Or give some advice?
Input string: '123456789'
Outputted CRC: CRC32: 0x22016B0A
Desired CRC: CRC32: 0xCBF43926
You made your array one word too short, and so overwrote the allocated memory. It needs to be:
#define CRC32_BYTE_POSSIBLE_VALUES 256
Though that part probably still worked, because C.
You need to initialize the variable you are reversing into:
uint32_t toret = 0;
These lines:
top_byte = (uint8_t)(reg >> 24);
reg = (reg << 8) | inverse_byte(data[i]);
need to be:
top_byte = (uint8_t)(reg >> 24) ^ inverse_byte(data[i]);
reg <<= 8;
and you need to delete these lines:
for (size_t i = 0; i < 4; i++) {
top_byte = (uint8_t) (reg >> 24);
reg = (reg << 8) ;
reg ^= __crc32_table[top_byte];
}
Then you get the right answer.
If you would like to implement the table approach on the augmented message as described in Chapter 9 (requiring another four iterations of the CRC at the end as in your code), then you need to first read these important notes in the document:
Note: The initial register value for this algorithm must be the
initial value of the register for the previous algorithm fed through
the table four times. Note: The table is such that if the previous
algorithm used 0, the new algorithm will too.
To get the same effect as the initial value of 0xffffffff (notably not zero) with the non-augmented message version, which is how that standard CRC is defined, then you'd need to find an initial value such that applying 32 zero bits to it using the CRC gives you 0xffffffff. That value is 0x46af6449, obtained by reversing the CRC bit-wise algorithm:
uint32_t x = -1;
for (unsigned i = 0; i < 32; i++)
x = x & 1 ? ((x ^ 0x4c11db7) >> 1) | 0x80000000 : x >> 1;
Then your code will work if you fix the array size and the toret initialization errors, and simply replace:
uint32_t reg = -1;
with:
uint32_t reg = 0x46af6449;
Either augmented or not, reversing every single input byte as you are doing is a waste of time. You can and should instead just reverse the calculation and the polynomial. See rcgldr's answer.
Example code using right shifting CRC (0xedb88320 is a reflected version of 0x04C11DB7):
#include <iostream>
#include <iomanip>
typedef unsigned char uint8_t;
typedef unsigned int uint32_t;
uint32_t crctbl[256];
void gentbl(void)
{
uint32_t crc;
uint32_t c;
uint32_t i;
for(c = 0; c < 0x100; c++){
crc = c;
for(i = 0; i < 8; i++){
crc = (crc & 1) ? (crc >> 1) ^ 0xedb88320 : (crc >> 1);
}
crctbl[c] = crc;
}
}
uint32_t crc32(uint8_t * bfr, size_t size)
{
uint32_t crc = 0xfffffffful;
while(size--)
crc = (crc >> 8) ^ crctbl[(crc & 0xff) ^ *bfr++];
return(crc ^ 0xfffffffful);
}
int main(int argc, char**argv)
{
uint32_t crc;
uint8_t msg[10] = "123456789";
gentbl();
crc = crc32(msg, 9);
std::cout << "crc " << std::hex << std::setw(8) << std::setfill('0') << crc << std::endl;
return(0);
}

Trying to remove a value from a set which is constructed using bitvector

Im trying to remove value from a set but can't get it to work
this is the struct
struct set {
int capacity;
int size;
char *array;
};
This is how i insert the values in to the set
void set_insert(const int value, set *s)
{
if (!set_member_of(value, s))
{
int bit_in_array = value; // To make the code easier to read
// Increase the capacity if necessary
if (bit_in_array >= s->capacity)
{
int no_of_bytes = bit_in_array / 8 + 1;
s->array = realloc(s->array, no_of_bytes);
for (int i = s->capacity / 8 ; i < no_of_bytes ; i++)
{
s->array[i] = 0;
}
s->capacity = no_of_bytes * 8;
}
// Set the bit
int byte_no = bit_in_array / 8;
int bit = 7 - bit_in_array % 8;
s->array[byte_no] = s->array[byte_no] | 1 << bit;
s->size++;
}
}
This is how i've tried to remove the values. I don't know why but
it completely ruins the set and assigns different values to the
entire array
void set_remove(const int value, set *const s)
{
int byte_no = value / 8;
if(set_member_of(value, s))
{
s->array[byte_no] = 0;
s->size--;
}
}
You didn't post set_member_of, so I had to synthesize it.
The main issue with set_remove is that it is zeroing out all bits in the given byte. You want to and against the complement of the bit mask. So, change this:
s->array[byte_no] = 0;
Into:
s->array[byte_no] &= ~mask;
When I do bit masks, I like to use macros instead of shifts/divides/etc in multiple places.
In set_insert, I think it's easier to make capacity be number of bytes rather than number of bits.
Although char for the array type works, using unsigned char is probably better.
Note that as you define set, under C, it is not a type.
Anyway, here is the refactored code. I've compiled it but not tested it:
#include <stdlib.h>
typedef unsigned char atom;
typedef struct set {
int capacity;
int size;
atom *array;
} set;
#define INDEX(_bitno) ((_bitno) / 8)
#define MASK(_bitno) (7 - ((_bitno) % 8))
int
set_member_of(int bitno,set *s)
{
int byte_no = INDEX(bitno);
atom mask = MASK(bitno);
atom match = 0;
if (byte_no < s->capacity)
match = s->array[byte_no] & mask;
return match;
}
void
set_insert(int bitno, set *s)
{
if (! set_member_of(bitno, s)) {
int newcap = INDEX(bitno + 8);
// Increase the capacity if necessary
if (newcap > s->capacity) {
s->array = realloc(s->array, newcap);
// zero out any new cells
for (int i = s->capacity; i < newcap; ++i)
s->array[i] = 0;
s->capacity = newcap;
}
atom mask = MASK(bitno);
int byte_no = INDEX(bitno);
s->array[byte_no] |= mask;
s->size++;
}
}
void
set_remove(int bitno, set *s)
{
if (set_member_of(bitno, s)) {
int byte_no = INDEX(bitno);
atom mask = MASK(bitno);
s->array[byte_no] &= ~mask;
s->size--;
}
}

Conversion of int to bit wrong return type

i have developed a function to convert int to 32 bits. the problem is i am trying to put the returned bits into array type of int but it's not coming. Should i use char array. As i need to pass the bits to another function bit by bit so i need to store them in array. Below is the code:
int main()
{
int x=24; // int whose 32 bits i need
int n=32; // number of bits needed
int p=0; // starting position.
int py[32]=getBits(x,p,n);
printf("\n",py);
return 0;
}
unsigned getBits(unsigned x, unsigned p, unsigned n) {
return (x >> (p + 1 - n)) & ~(~0 << n);
}
There is a lot wrong here, such as the assignment at run time to the array.
To store the separate bits of a 32-bit int into the array elements, you could use something as follows.
//assumes bits has been declared as unsignef char bits[32]
void get_bits32(unsigned char * bits, unsigned int x) {
for(int i = 0; i < 32; i++)
bits[i] = (x >> i) & 1u;
}
You could modify this to specify the number of bits or length of the array as follows.
void get_bits32(unsigned char * bits, int n, unsigned int x) {
for(int i = 0; i < n; i++)
bits[i] = (x >> i) & 1u;
}
Here a char array is used, as you anticipate only 0s or 1s.
This version stores the least significant bit at position 0 of the array.
To print this, you must print each element of the array, ex.
for(int i = 0; i < n; i++)
printf("%d", bits[i]);

Trouble printing decimal to binary number properly

I'm trying to write code to print the binary representation of a number. This was my attempt:
#include <stdio.h>
void getBinary(int num);
int main(void) {
int num = 2;
getBinary(num);
return 0;
}
void getBinary(int num) {
int mask = 1 << 31, i;
int temp;
for (i = 31; i >= 0; i--) {
temp = num & mask;
if (temp > 0)
printf("1");
else
printf("0");
mask = mask >> 1;
}
printf("\n");
}
And this doesn't work. If i make num = 2 my output will be ...0011. This is the answer I was given:
void getBinary(int);
int main()
{
int num=0;
printf("Enter an integer number :");
scanf("%d",&num);
printf("\nBinary value of %d is =",num);
getBinary(num);
return 0;
}
/*Function definition : getBinary()*/
void getBinary(int n)
{
int loop;
/*loop=15 , for 16 bits value, 15th bit to 0th bit*/
for(loop=15; loop>=0; loop--)
{
if( (1 << loop) & n)
printf("1");
else
printf("0");
}
}
and this will give the correct output. Why? What is different between my code and this. Aren't they doing the same thing with the solution doing it in fewer steps?
#include <stdio.h>
void getBinary(int num);
int main(void) {
unsigned int num = 2;
getBinary(num);
return 0;
}
void getBinary(int num) {
unsigned int mask = 1 << 31;
int i;
unsigned int temp;
for (i = 31; i >= 0; i--) {
temp = num & mask;
if (temp > 0)
printf("1");
else
printf("0");
mask = mask >> 1;
}
printf("\n");
}
For those curious, this is the correct answer. Just make the mask unsigned.
You have some problems in the code:
1 << 31 invokes undefined behavior because of signed arithmetic overflow. On your platform it most likely produces the value INT_MIN, that has the expected bit configuration but is negative.
temp > 0 might fail incorrectly if num < 0, because the sign bit will make temp negative too.
shifting mask to the right when its value is negative has an implementation defined result: On your platform it duplicates the sign bit, therefore mask will not have a single bit as expected, but all bits set above the current one. This explains the observed behavior.
You should use type unsigned int in function getBinary for num, temp and mask to get correct behavior.
Here is a corrected version of your code:
#include <stdio.h>
void getBinary(unsigned int num);
int main(void) {
unsigned int num = 2;
getBinary(num);
return 0;
}
void getBinary(unsigned int num) {
unsigned int mask = 1U << 31;
unsigned int temp;
for (int i = 31; i >= 0; i--) {
temp = num & mask;
if (temp != 0)
printf("1");
else
printf("0");
mask = mask >> 1;
}
printf("\n");
}
The proposed solution only prints 16 bits, which may or may not have been the specification. If the int type is larger than 16 bits, the bit shift will not overflow and everything is fine. If int has 16 bits, 1 << 15 invokes undefined behavior, so the solution is not strictly correct, but will function on most current platforms.
Here is a simpler solution:
void getBinary(unsigned int num) {
for (int shift = 32; shift-- > 0;) {
putchar('0' + ((num >> shift) & 1));
}
putchar("\n");
}
Initialize shift to 16 to print only the low order 16 bits.

Accessing a specific indexes in an array C

Hey guys so I wish to access an array in a sequential order
int get_value_from_array(char* buffer, int byte1, int byte2) {
int i;
int *j;
j = malloc(sizeof(int));
*j= 0;
for(i = 0; i < byte2 - byte1; i++) {
*j += (buffer[byte1+i] << (i*8));
}
return j;
}
I wish to get some value from point1 to point2 starting from point1. Each is 8 bytes so I shifted by 8. And I'm adding it to j and returning it with j. The way I got this array is by using mmap and reading off some fat.dat file. First of all, I am getting really wild values... I don't understand. I dereferenced j by setting its value as 0 and adding the values to j afterwards.
I have also been following this example. I am not allowed to use malloc to solve this question but then I am even more confused. I tried to use this without the pointers but then I would get floating point exception.
Can you please help me how to fix this?
==========EDIT=====================
ok maybe my question was not clear enough =[
int get_value_from_array(char* buffer, int byte1, int byte2) {
int i;
int j = 0;
for(i = 0; i < byte2 - byte1; i++) {
j += (buffer[byte1+i] << (i*8));
}
return j;
}
this was my first attempt to get this thing working but I kept getting floating point exception. I searched up some stuff and found that an alternative way to do this is casting the value into a pointer and dereferenccing it. I've made some attempts but it's not working so great (or at least returning the most random value + sometimes a seg fault). I hope this clarifies what I wish to do.
This may be what you're after.
int get_value_from_array(char* buffer, int byte1, int byte2)
{
int j = 0;
assert(buffer != 0);
assert(byte1 >= 0 && byte2 >= byte1 && (size_t)(byte2 - byte1) < sizeof(int));
for (int i = 0; i < byte2 - byte1; i++)
j += (unsigned char)buffer[byte1+i] << (i*8);
return j;
}
As noted in my comment, you really don't want to allocate int *j for multiple reasons, including "you aren't allowed to use malloc()" and "it leaks memory when misused as in your question".
And, honest, I wrote this code before I saw your update to the question!
The assert() and (unsigned char) cast are the only differences between your original code and this code. I'm not sure how you get a floating point exception out of that. You can get one of those if you divide by zero, but there isn't an obvious division in your code, let alone division by zero.
You should go back to your original code and print all the information out as it runs. Or use a debugger to step through it.
int get_value_from_array(char* buffer, int byte1, int byte2)
{
int j = 0;
printf("-->> %s: %p (%d..%d)\n", __func__, buffer, byte1, byte2);
assert(buffer != 0);
assert(byte1 >= 0 && byte2 >= byte1 && (size_t)(byte2 - byte1) < sizeof(int));
for (int i = 0; i < byte2 - byte1; i++)
{
printf("j0 = 0x%.8X, i = %d, byte = 0x%.2X, "
"add = 0x%.8X, j1 = 0x%.8X\n",
j, i, (unsigned char)buffer[byte1+i],
(unsigned char)buffer[byte1+i] << (i*8),
j + (unsigned char)buffer[byte1+i] << (i*8));
j += (unsigned char)buffer[byte1+i] << (i*8);
}
printf("<<-- %s: 0x%.8X\n", __func__, j);
return j;
}
Note that printing ends with a newline. In C99, __func__ is the name of the function; omit if you have C89/C90, and remove the %s — or replace %s with your function name (or replace __func__ with your function name as a string literal: "get_value_from_array").
Debuggable code written in C89/C90:
int get_value_from_array(char* buffer, int byte1, int byte2)
{
static const char func[] = "get_value_from_array";
int i;
int j = 0;
printf("-->> %s: %p (%d..%d)\n", func, buffer, byte1, byte2);
assert(buffer != 0);
assert(byte1 >= 0 && byte2 >= byte1 && (size_t)(byte2 - byte1) < sizeof(int));
for (i = 0; i < byte2 - byte1; i++)
{
printf("j0 = 0x%.8X, i = %d, byte = 0x%.2X, "
"add = 0x%.8X, j1 = 0x%.8X\n",
j, i, (unsigned char)buffer[byte1+i],
(unsigned char)buffer[byte1+i] << (i*8),
j + (unsigned char)buffer[byte1+i] << (i*8));
j += (unsigned char)buffer[byte1+i] << (i*8);
}
printf("<<-- %s: 0x%.8X\n", func, j);
return j;
}

Resources