版權聲明:您好,轉載請留下本人部落格的位址,謝謝 https://blog.csdn.net/hongbochen1223/article/details/45117691
在typeorder.h頭檔案中,主要定義了下面幾個函數,__u32 ___arch__swab32(__u32 val),___arch__swab64(__u64 val);這兩個函數的含義基本上是将32位寄存器中的位元組次序變反,将64位寄存器中的位元組次序變反。
舉個列子,有一個以16進制表示的32位變量,a=0x12345678;其中由于其是十六進制的,是以12占一個位元組,34占一個位元組,56占一個位元組,78占一個位元組,則執行上述___arch__swab32(__u32 val)函數之後,其位元組次序變反,就變成了a=0x78563412了。
下面是tyepeorder.h的源代碼,其中的解釋以及學習部分都在注釋當中,中間在處理64位的時候,有一段代碼我看到就會感到很高興,在注釋中會有展現的。
#ifndef _I386_BYTEORDER_H
#define _I386_BYTEORDER_H
#include <asm/types.h>
#include <linux/compiler.h>
#ifdef __GNUC__
/* For avoiding bswap on i386 */
//未實作
#ifdef __KERNEL__
#endif
//該内聯函數的作用是将x的位元組次序反轉
static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x)
{
//bswap指令 是将32位寄存器中的位元組的次序變反
#ifdef CONFIG_X86_BSWAP //如果定義了bswap指令,則直接執行該指令
__asm__("bswap %0" : "=r" (x) : "0" (x));
//xchgb:交換字或者是位元組,至少有一個操作書是寄存器,段寄存器不能作為操作數
#else
/*
* 思想就是先交換低位元組,将低位元組循環左移16位,高位元組被換到了低位元組位置,再交換位元組
*/
__asm__("xchgb %b0,%h0\n\t" /* swap lower bytes,*/
"rorl $16,%0\n\t" /* swap words */
"xchgb %b0,%h0" /* swap higher bytes */
:"=q" (x)
: "0" (x));
#endif
return x;
}
//該内聯函數的作用是将64位位元組的次序變反
/**
* 他的思想是:
* 首先,将64位的先變成兩個32位的儲存到一個結構中,
* 同時與一個64位的變量儲存到一個共同體中,在
* 這裡,真心能夠感受到核心代碼的能省記憶體盡量省的優雅了。
* 雖然說這是一種不太美觀的強制類型轉換,直接将類型省了,
* 但是這樣的處理還是非常棒的。
*
* 如果定義了bswap彙編指令,則現将其中的兩個32位的變量的位元組交換,
* 再将兩個32位的位元組交換。
* 如果沒有定義bswap指令,則先對其中的兩個32位的變量執行上面的
* ___arch__swab32函數,最後再将這兩函數個變量交換
*
*/
static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 val)
{
union {
struct { __u32 a,b; } s;
__u64 u;
} v;
v.u = val;
#ifdef CONFIG_X86_BSWAP
asm("bswapl %0 ; bswapl %1 ; xchgl %0,%1"
: "=r" (v.s.a), "=r" (v.s.b)
: "0" (v.s.a), "1" (v.s.b));
#else
v.s.a = ___arch__swab32(v.s.a);
v.s.b = ___arch__swab32(v.s.b);
asm("xchgl %0,%1" : "=r" (v.s.a), "=r" (v.s.b) : "0" (v.s.a), "1" (v.s.b));
#endif
return v.u;
}
/* Do not define swab16. Gcc is smart enough to recognize "C" version and
convert it into rotation or exhange. */
/* 不用定義16位的位元組變反函數,因為gcc是非常聰明的,他能夠識别“C”版本,并且
将其轉化成旋轉或者是交換 */
#define __arch__swab64(x) ___arch__swab64(x)
#define __arch__swab32(x) ___arch__swab32(x)
#define __BYTEORDER_HAS_U64__
#endif /* __GNUC__ */
#include <linux/byteorder/little_endian.h>
#endif /* _I386_BYTEORDER_H */
學了之前的GCC内嵌彙編之後,看其中的彙編的時候就不會那麼吃力了。