Bitcpy

两种bitcpy的实现方式

1. 显示数据bits

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#define HALF_WORD   uint16_t
#define WORD uint32_t
void showBits(void* d, int len) {
int bytes = len / 8;
unsigned char* p = (unsigned char*)d;
for (int i = 0; i < bytes; i++) {
unsigned char tmp = 0x80;
for (int j = 0; j < 8; j++) {
if (tmp & *p)
printf("1");
else
printf("0");
tmp >>= 1;
}
printf(" ");
++p;
}
printf("\n");
}

2. bitcpy 算术方式

拷贝方式是从单个字节的低位开始拷贝,进位式拷贝。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
int bitcopy(void* to, unsigned int tOfs, int tCnt, const void* from, unsigned int fOfs, int fCnt) {
int BitsOfHalfWord = sizeof(HALF_WORD) * 8;
// align data and offset to HALF_WORD
to = (void*)((intptr_t)to + (tOfs / BitsOfHalfWord) * sizeof(HALF_WORD));
from = (void*)((intptr_t)from + (fOfs / BitsOfHalfWord) * sizeof(HALF_WORD));
fOfs %= BitsOfHalfWord;
tOfs %= BitsOfHalfWord;

int NbrOfCopiedBits = 0, bCnt = (fCnt < tCnt) ? fCnt : tCnt;
WORD rMask, wMask;
WORD temp, * _to = (WORD*)to, * _from = (WORD*)from;
while (bCnt > 0) {
// update counter
int BitsToCopy = (bCnt < BitsOfHalfWord) ? bCnt : BitsOfHalfWord;
bCnt -= BitsToCopy;
NbrOfCopiedBits += BitsToCopy;
// mask reading from '_from' and mask writing to '_to'
rMask = (((WORD)-1) << fOfs) ^ (((WORD)-1) << (fOfs + BitsToCopy));
wMask = (((WORD)-1) << tOfs) ^ (((WORD)-1) << (tOfs + BitsToCopy));
showBits(&rMask, 32);
showBits(&wMask, 32);
temp = (*_from & rMask) >> fOfs << tOfs;
*_to &= ~wMask;
*_to |= temp;
printf("%d bit(s) copied\n", BitsToCopy);
// increase data pointer if copy is not completed
if (BitsToCopy == BitsOfHalfWord) {
_to = (WORD*)((intptr_t)_to + sizeof(HALF_WORD));
_from = (WORD*)((intptr_t)_from + sizeof(HALF_WORD));
}
showBits(to, 64);
}
return NbrOfCopiedBits;
}

3. bitcpy 物理方式

物理左移

1
2
3
4
5
6
7
8
9
10
11
12
13
14
WORD shiftLeft(WORD w, int len) {
unsigned char* s = (unsigned char*)&w;
while (len--) {
*(s) <<= 1;
for (int i = 1; i < 4; i++) {
if (*(s + i) == 0)
continue;
if (*(s + i) & 0x80)
*(s + i - 1) |= 1;
*(s + i) <<= 1;
}
}
return w;
}

物理右移

1
2
3
4
5
6
7
8
9
10
11
12
13
14
WORD shiftRight(WORD w, int len) {
unsigned char* s = (unsigned char*)&w;
while (len--) {
*(s+3) >>= 1;
for (int i = 2; i >= 0; i--) {
if (*(s + i) == 0)
continue;
if (*(s + i) & 1)
*(s + i + 1) |= 0x80;
*(s + i) >>= 1;
}
}
return w;
}

拷贝方式是按照实际的物理bit位进行顺序拷贝的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
int bitcpy(void* to, unsigned int tOfs, const void* from, unsigned int fOfs, int bCnt) {
int BitsOfHalfWord = sizeof(HALF_WORD) * 8;
// 将数据和偏置对其“半字”
// 指针视为intptr_t,加1则前进一个Byte,且更安全(适用于将指针进行算术运算时使用)
to = (void*)((intptr_t)to + (tOfs / BitsOfHalfWord) * sizeof(HALF_WORD));
from = (void*)((intptr_t)from + (fOfs / BitsOfHalfWord) * sizeof(HALF_WORD));
fOfs %= BitsOfHalfWord;
tOfs %= BitsOfHalfWord;
int NbrOfCopiedBits = 0;
WORD rMask, wMask;
WORD temp;
WORD *_to = (WORD*)to;
WORD *_from = (WORD*)from;
while (bCnt > 0) {
// 更新
int BitsToCopy = (bCnt < BitsOfHalfWord) ? bCnt : BitsOfHalfWord;
bCnt -= BitsToCopy;
NbrOfCopiedBits += BitsToCopy;
// 源与目标的遮罩
rMask = shiftRight((WORD)-1, fOfs) ^ shiftRight((WORD)-1, fOfs + BitsToCopy);
wMask = shiftRight((WORD)-1, tOfs) ^ shiftRight((WORD)-1, tOfs + BitsToCopy);
temp = (*_from & rMask);
temp = shiftLeft(temp, fOfs);
temp = shiftRight(temp, tOfs);
*_to &= ~wMask; // 先清理此部分
*_to |= temp; // 在“拷贝”进来
// 拷贝未完成情况下,跟进指针
if (BitsToCopy == BitsOfHalfWord) {
_to = (WORD*)((intptr_t)_to + sizeof(HALF_WORD));
_from = (WORD*)((intptr_t)_from + sizeof(HALF_WORD));
}
}
return NbrOfCopiedBits;
}