Bitwise memmove

实现按位memmove的最佳方法是什么? 该方法应该采用额外的目标和源位偏移,并且计数也应该是位。

  • 我看到ARM提供了一个非标准的_membitmove ,它正是我所需要的,但我找不到它的来源。
  • Bind的bitset包括isc_bitstring_copy ,但效率不高
  • 我知道C标准库没有提供这样的方法,但我也找不到提供类似方法的任何第三方代码。

由于Highlevel语言提供的最小单位为1 Byte,因此没有标准函数可以为您提供此选项。 也许你可以寻找提供这些function的第三方库,但你必须自己编写代码。

假设“最佳”意味着“最简单”,您可以逐个复制位。 从概念上讲,位的地址是一个对象(结构),它具有指向内存中字节的指针和字节中位的索引。

 struct pointer_to_bit { uint8_t* p; int b; }; void membitmovebl( void *dest, const void *src, int dest_offset, int src_offset, size_t nbits) { // Create pointers to bits struct pointer_to_bit d = {dest, dest_offset}; struct pointer_to_bit s = {src, src_offset}; // Bring the bit offsets to range (0...7) dp += db / 8; // replace division by right-shift if bit offset can be negative db %= 8; // replace "%=8" by "&=7" if bit offset can be negative sp += sb / 8; sb %= 8; // Determine whether it's OK to loop forward if (dp < sp || dp == sp && db <= sb) { // Copy bits one by one for (size_t i = 0; i < nbits; i++) { // Read 1 bit int bit = (*sp >> sb) & 1; // Write 1 bit *dp &= ~(1 << db); *dp |= bit << db; // Advance pointers if (++sb == 8) { sb = 0; ++sp; } if (++db == 8) { db = 0; ++dp; } } } else { // Copy stuff backwards - essentially the same code but ++ replaced by -- } } 

如果你想编写一个针对速度优化的版本,你将不得不按字节(或更好,单词)进行复制,展开循环,并处理一些特殊情况( memmove会这样做;你必须做更多,因为你的function更复杂)。

PS哦,看到你调用isc_bitstring_copy效率低下,你可能想要速度优化。 您可以使用以下想法:

单独开始复制位,直到目标字节对齐( db == 0 )。 然后,很容易一次复制8位,做一些小事。 这样做直到剩下少于8位复制; 然后继续逐个复制位。

 // Copy 8 bits from s to d and advance pointers *dp = *s.p++ >> sb; *d.p++ |= *sp << (8 - sb); 

PPS哦,看到你对将要使用代码的评论,你真的不需要实现所有版本(byte / halfword / word,big / little-endian); 你只想要最简单的一个 - 使用单词( uint32_t )。

这是部分实现(未测试)。 有明显的效率和可用性改进。

src n个字节复制到dest (不重叠src ),并将dest bit向右移位位,0 <= bit <= 7.这假设最低有效位位于字节的右侧

 void memcpy_with_bitshift(unsigned char *dest, unsigned char *src, size_t n, int bit) { int i; memcpy(dest, src, n); for (i = 0; i < n; i++) { dest[i] >> bit; } for (i = 0; i < n; i++) { dest[i+1] |= (src[i] << (8 - bit)); } } 

一些改进:

  • 不要在dest开头覆盖第bit
  • 合并循环
  • 有办法复制一些不能被8整除的位
  • 在char中修复> 8位