shift a block of memory content

Y

yancheng.cheok

hello all,

in my memory content says,
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8 ... 0xff

i wish to shift it n bits. please note that, not n bye, but n bit, and
n can be any value 0, 1, 2......

let's say n = 8,

the memory content i wish to get is
0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8 ... 0xff, 0x0

i was wondering c got any facilities to do so. i had once try int
pointer, but the result i will get is
0x1, 0x2, 0x3, 0x0, 0x5, 0x6, 0x7, 0x0 ....

any suggestion? or do i need to use assembly?

thank you.

yccheok
 
R

Richard Heathfield

(e-mail address removed) said:
hello all,

in my memory content says,
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8 ... 0xff

i wish to shift it n bits. please note that, not n bye, but n bit, and
n can be any value 0, 1, 2......

let's say n = 8,

the memory content i wish to get is
0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8 ... 0xff, 0x0

i was wondering c got any facilities to do so. i had once try int
pointer, but the result i will get is
0x1, 0x2, 0x3, 0x0, 0x5, 0x6, 0x7, 0x0 ....

any suggestion? or do i need to use assembly?

You don't need assembly language, that's for sure.

At the most basic level, you can do this using bit-twiddling macros:

#include <limits.h>

#define SET_BIT(a, b) \
(a)[(b) / CHAR_BIT] |= (1 << ((b) % CHAR_BIT))
#define CLEAR_BIT(a, b) \
(a)[(b) / CHAR_BIT] &= ~(1 << ((b) % CHAR_BIT))
#define TEST_BIT(a, b) \
(!!(((a)[(b) / CHAR_BIT]) & (1 << ((b) % CHAR_BIT))))

unsigned char buf[] = { 0, 1, 2, 3, 4, 5 };
size_t i = 0;
size_t bits = sizeof buf * CHAR_BIT;

int leftmost = TEST_BIT(buf, 0);
while(++i < bits)
{
if(TEST_BIT(buf, i))
{
SET_BIT(buf, i - 1);
}
else
{
CLEAR_BIT(buf, i - 1);
}
}
if(rotating && leftmost)
{
SET_BIT(buf, bits - 1);
}
else
{
CLEAR_BIT(buf, bits - 1);
}

It can certainly be done more efficiently than this (by constructing masks
for all the bits that will cross byte boundaries, and shifting all the bits
that don't), but you have the general idea. Making it faster is left as an
exercise.

(I've got code to do this the "quick" way, but I didn't write it to be
standalone, alas. Mental note to self: must re-factor.)
 
S

spibou

(e-mail address removed) said:

You are assuming here that each memory cell contains exactly 8 bits.
This may be true on your platform but it is not generally true. Notice
how Richard's code following below uses the CHAR_BIT constant to
achieve platform independence.


Richard said:
You don't need assembly language, that's for sure.

At the most basic level, you can do this using bit-twiddling macros:

#include <limits.h>

#define SET_BIT(a, b) \
(a)[(b) / CHAR_BIT] |= (1 << ((b) % CHAR_BIT))
#define CLEAR_BIT(a, b) \
(a)[(b) / CHAR_BIT] &= ~(1 << ((b) % CHAR_BIT))
#define TEST_BIT(a, b) \
(!!(((a)[(b) / CHAR_BIT]) & (1 << ((b) % CHAR_BIT))))

unsigned char buf[] = { 0, 1, 2, 3, 4, 5 };
size_t i = 0;
size_t bits = sizeof buf * CHAR_BIT;

int leftmost = TEST_BIT(buf, 0);
while(++i < bits)
{
if(TEST_BIT(buf, i))
{
SET_BIT(buf, i - 1);
}
else
{
CLEAR_BIT(buf, i - 1);
}
}
if(rotating && leftmost)
{
SET_BIT(buf, bits - 1);
}
else
{
CLEAR_BIT(buf, bits - 1);
}
 
T

tomstdenis

(e-mail address removed) said:


You are assuming here that each memory cell contains exactly 8 bits.
This may be true on your platform but it is not generally true. Notice
how Richard's code following below uses the CHAR_BIT constant to
achieve platform independence.

There are times where you just care about the minimums though. He may
only want to store upto 8 bits per char.

Tom
 
R

Richard Heathfield

(e-mail address removed) said:
There are times where you just care about the minimums though. He may
only want to store upto 8 bits per char.

In which case, he'll want to have those 8 bits in a place where they can
easily be accessed, in which case he'll need to shift them CHAR_BIT bits to
keep them within the bottom 8 bits of the byte.
 
T

tomstdenis

Richard said:
In which case, he'll want to have those 8 bits in a place where they can
easily be accessed, in which case he'll need to shift them CHAR_BIT bits to
keep them within the bottom 8 bits of the byte.

for (x = 0; x < n-1; x++) {
a[x] = ((a[x] >> L) | (a[x+1] << (8-L))) & 0xFF;
}
a[n-1] >>= L;

Right shift by a value L=0...7

Assuming a[] is an unsigned array type ...

If you are just assuming char holds 8 bits [not correct but also not
entirely bad] then you need not CHAR_BIT.

I agree though, for PROPER code you should, but you also don't have to
extract one bit at a time to do the shift.

http://math.libtomcrypt.com

Is a portable bignum library used pretty much, well, "everywhere".
It's part of Tcl for instance, and used wherever TCL is used.

Tom
 
R

Richard Heathfield

(e-mail address removed) said:
...you also don't have to
extract one bit at a time to do the shift.

Yes, I know, and I hinted as much in my original reply.
 
T

tomstdenis

Richard said:
(e-mail address removed) said:


Yes, I know, and I hinted as much in my original reply.

Oh, now you supposed I'm reading the entire reply... hehehe

My bad ... Just bored, killing off the time until I move ...

Tom
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top