首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

Linux內核位操作精髓:8/16/32位整數高低位交換算法

     編輯:關於C

Linux 內核中蘊含大量經典位操作算法,其中字節序轉換(高低位交換)是網絡編程、文件格式解析、驅動開發的高頻需求。本文提煉內核源碼中的 bswap_8/16/32 實現,詳細解析位運算邏輯,附完整可運行代碼與測試結果。

核心代碼(源自 Linux 內核)

#include 

/* 8 位:交換高低 4 位(半字節交換) */
static inline unsigned char bswap_8(unsigned char v) {
    return ((v & 0xff) << 4) | (v >> 4);
}

/* 16 位:交換高低 8 位(字節交換) */
static inline unsigned short bswap_16(unsigned short v) {
    return ((v & 0xff) << 8) | (v >> 8);
}

/* 32 位:交換高低 16 位(雙字交換),實際為完整字節序反轉 */
static inline unsigned int bswap_32(unsigned int v) {
    return ((v & 0xff) << 24) |
           ((v & 0xff00) << 8) |
           ((v & 0xff0000) >> 8) |
           (v >> 24);
}

位運算邏輯圖解

bswap_8:半字節交換

原值: 0xAB = 1010 1011
v & 0xff = 0xAB
(v & 0xff) << 4 = 1011 0000 (0xB0)  ← 低 4 位移到高 4 位
v >> 4 = 0000 1010 (0x0A)           ← 高 4 位移到低 4 位
結果: 0xB0 | 0x0A = 0xBA = 1011 1010

bswap_16:字節交換

原值: 0x1234 = 00010010 00110100
(v & 0xff) << 8 = 00110100 00000000 (0x3400)  ← 低字節移到高字節
v >> 8 = 00000000 00010010 (0x0012)           ← 高字節移到低字節
結果: 0x3400 | 0x0012 = 0x3412

bswap_32:完整字節序反轉

原值: 0x11223344
第 1 字節 (最低): 0x44 → 移至最高位: 0x44000000
第 2 字節:        0x33 → 移至次高位: 0x00330000
第 3 字節:        0x22 → 移至次低位: 0x00002200
第 4 字節 (最高): 0x11 → 移至最低位: 0x00000011
結果: 0x44332211
掩碼與移位組合完美實現無分支字節序轉換。

完整測試程序

int main() {
    unsigned short v = 0x1000;
    printf("1、\n原來的 v: %d (0x%x)\n", v, v);
    printf("16位高低8位轉換後: %d (0x%x) =========> 0x%x ---> %d\n",
           v, v, bswap_16(v), bswap_16(v));

    unsigned char a = 0x0a;
    printf("\n2、\n原來的 a: %d (0x%x)\n", a, a);
    printf("8位高低4位轉換後: %d (0x%x) ===========> 0x%x ---> %d\n",
           a, a, bswap_8(a), bswap_8(a));

    unsigned int b = 0x00001111;
    printf("\n3、\n原來的 b: %d (0x%x)\n", b, b);
    printf("32位高低16位轉換後: %d (0x%x) ========> 0x%x ---> %d\n",
           b, b, bswap_32(b), bswap_32(b));

    return 0;
}

運行結果

1、
原來的 v: 4096 (0x1000)
16位高低8位轉換後: 4096 (0x1000) =========> 0x0010 ---> 16

2、
原來的 a: 10 (0xa)
8位高低4位轉換後: 10 (0xa) ===========> 0xa0 ---> 160

3、
原來的 b: 4369 (0x1111)
32位高低16位轉換後: 4369 (0x1111) ========> 0x11110000 ---> 286326784

驗證:

  • 0x1000 → 低字節 0x00、高字節 0x10 → 交換後 0x0010 = 16 ✓
  • 0x0A → 高 4 位 0、低 4 位 0xA → 交換後 0xA0 = 160 ✓
  • 0x00001111 → 字節序反轉為 0x11110000 ✓

擴展:64 位交換與標準庫

// 64 位版本(內核常用 __swab64)
static inline unsigned long long bswap_64(unsigned long long v) {
    return ((v & 0xffULL) << 56) |
           ((v & 0xff00ULL) << 40) |
           ((v & 0xff0000ULL) << 24) |
           ((v & 0xff000000ULL) << 8) |
           ((v & 0xff00000000ULL) >> 8) |
           ((v & 0xff0000000000ULL) >> 24) |
           ((v & 0xff000000000000ULL) >> 40) |
           (v >> 56);
}

// 現代 C 直接使用標準庫(GCC/Clang/MSVC 均內建優化)
#include   // Linux
// 或 #include   // bswap_16/32/64
// Windows: _byteswap_ushort/ulong/uint64

總結

Linux 內核的 bswap 系列展示了無分支、純位運算的極致優雅:

  1. 掩碼提取:& 0xff 等隔離目標字節/半字節。
  2. 移位定位:<< / >> 將片段移至目標位置。
  3. 或運算合成:| 組裝最終結果。

這類代碼無循環、無分支、指令極少,編譯器極易優化為單條指令(如 x86 bswap、ARM rev)。掌握這套模板,應對任意位寬字節序轉換得心應手。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved