乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Linux Kernel內(nèi)核字節(jié)序源代碼分析-swab.h和big_endian.h — ...

       崗西老蔡 2010-05-08

      Linux Kernel內(nèi)核字節(jié)序源代碼分析-swab.h和big_endian.h

      Linux Kernel 2.6.14-內(nèi)核字節(jié)序源代碼分析-swab.h和big_endian.h
      轉(zhuǎn)載
      **************************************************
      -----------------------------------------------------
      分析1:
      以下?lián)﨤inux Kernel中的注釋:it doesn't pollute the POSIX namespace. Use these in the header files exported to user space.說明可用于用戶空間。
      typedef __signed__ char __s8;
      typedef unsigned char __u8;

      typedef __signed__ short __s16;
      typedef unsigned short __u16;

      typedef __signed__ int __s32;
      typedef unsigned int __u32;

      ------------自己加上的,為了后面的分析用
      typedef __signed__ long long __s64;
      typedef unsigned long long __u64;
      ------------------------------------------------------
      分析2:
      以下?lián)﨤inux Kernel中的注釋:These aren't exported outside the kernel to avoid name space clashes.只用于內(nèi)核空間,以防命名沖突。
      typedef signed char s8;
      typedef unsigned char u8;

      typedef signed short s16;
      typedef unsigned short u16;

      typedef signed int s32;
      typedef unsigned int u32;

      typedef signed long long s64;
      typedef unsigned long long u64;

      附:typedef 的使用說明:
      1.typedef跟變量一樣有可視范圍,并且內(nèi)層的可以覆蓋外層的。
      例如:
      int main(void)
      {
      typedef int INT32;
      INT32 a;
      ...
      }
      void fun()
      {
      typedef long INT32;
      INT32 B;
      ...
      }
      main中的INT32為int型,而fun中的INT32為long型,但它們?cè)谧约旱淖饔梅秶铼?dú)立起作用,互不干擾。

      2.在同一作用范圍內(nèi),不能用相同的名字來定義不同的數(shù)據(jù)類型。
      如:
      int main(void)
      {
      typedef int INT32;
      typedef long INT32;//--->錯(cuò)誤
      ...
      }
      即使是一模一樣的也不能重復(fù)出現(xiàn)。
      int main(void)
      {
      typedef int INT32;
      typedef int INT32;//--->錯(cuò)誤
      ...
      }
      但在c++中,一模一樣的可以重復(fù)出現(xiàn)。即:c++允許完全相同的typedef表達(dá)式多次出現(xiàn)。

      3.比較1:
      3-1.
      #define String char *
      String input,output;
      其展開后的結(jié)果為:
      char * input,output;這時(shí)input為char *型,而output為char 型。因?yàn)?是右結(jié)合的。
      3-2.
      typedef char * String;
      String input,output;
      其展開后的結(jié)果為:
      char * input, *output; input ,output均為char *型。
      typedef定義的類型對(duì)每一個(gè)變量都起作用。

      比較2:
      #define INT32 int
      unsigned INT32 a;-------->這是對(duì)的。可以組合使用。
      typedef int INT32;
      unsigned INT32 a;-------->這是錯(cuò)的,typedef不可以組合使用。

      4.一個(gè)難點(diǎn):
      typedef char * String;
      const String s;
      問:展開后到底是const char * s; 還是char * const s;
      答:展開后是char * const s;
      原因:const 修飾的為String,而String為一個(gè)指針,所以const就修飾指針去了。

      ***************************************************
      -------------------__swab16()----------------------
      \byteorder\swab.h的源代碼
      #define ___swab16(x) \
      ({ \
      __u16 __x = (x); \
      ((__u16)( \
      (((__u16)(__x) & (__u16)0x00ffU) << 8) | \
      (((__u16)(__x) & (__u16)0xff00U) >> 8) )); \
      })

      分析:
      1.__x與x,中間臨時(shí)變量用同名,但前面加上“__”
      2.U為無符號(hào)數(shù),0x00ffU,注意數(shù)字部分用小寫,U用大寫,前面加0x
      3.代碼精彩之處為:先用(__u16)(__x) & (__u16)(0x00ffU)進(jìn)行類型轉(zhuǎn)換,再用移位運(yùn)算。
      ((__u16)(__x) & (__u16)0x00ffU) << 8)
      和((__u16)(__x) & (__u16)0xff00U) >> 8)
      兩者結(jié)果再用或運(yùn)算。
      4.___swab16()前面有三個(gè)下劃線,而不是兩根下劃線。
      5.此處的宏定義為小寫,即是將其視為函數(shù)來處理。
      -----------------------___swab32()--------------------
      #define ___swab32(x) \
      ({ \
      __u32 __x = (x); \
      ((__u32)( \
      (((__u32)(__x) & (__u32)0x000000ffUL) << 24) | \
      (((__u32)(__x) & (__u32)0x0000ff00UL) << 8) | \
      (((__u32)(__x) & (__u32)0x00ff0000UL) >> 8) | \
      (((__u32)(__x) & (__u32)0xff000000UL) >> 24) )); \
      })
      分析:
      1.為長整型,UL,比如說:0x000000ffUL
      2.這種很長的宏:
      一要注意強(qiáng)制類型轉(zhuǎn)換;
      二要注意U,UL,ULL標(biāo)志其數(shù)據(jù)類型;
      三要注意宏內(nèi)最后用‘;’結(jié)尾,宏外用({ 宏體部分});
      四要注意每行用\ 來表示續(xù)行。
      3.寫法上注意對(duì)稱。中間臨時(shí)變量用雙下劃線__x,而函數(shù)則用三下劃線,如:___swab32()。
      ----------------------___swab64()----------------
      #define ___swab64(x) \
      ({ \
      __u64 __x = (x); \
      ((__u64)( \
      (__u64)(((__u64)(__x) & (__u64)0x00000000000000ffULL) << 56) | \
      (__u64)(((__u64)(__x) & (__u64)0x000000000000ff00ULL) << 40) | \
      (__u64)(((__u64)(__x) & (__u64)0x0000000000ff0000ULL) << 24) | \
      (__u64)(((__u64)(__x) & (__u64)0x00000000ff000000ULL) << 8) | \
      (__u64)(((__u64)(__x) & (__u64)0x000000ff00000000ULL) >> 8) | \
      (__u64)(((__u64)(__x) & (__u64)0x0000ff0000000000ULL) >> 24) | \
      (__u64)(((__u64)(__x) & (__u64)0x00ff000000000000ULL) >> 40) | \
      (__u64)(((__u64)(__x) & (__u64)0xff00000000000000ULL) >> 56) )); \
      })
      主干部分源代碼分析同上。
      #if defined(__KERNEL__)
      #define swab16 __swab16
      #define swab32 __swab32
      #define swab64 __swab64
      ... ...
      #endif
      Linux Kernel代碼風(fēng)格:
      1.先對(duì)__fun()或___fun()編寫實(shí)現(xiàn)代碼;
      2.再用宏定義fun()來替換__fun() ___fun();
      *****************************************************
      ----------------___constant_swab16()----------------
      #define ___constant_swab16(x) \
      ((__u16)( \
      (((__u16)(x) & (__u16)0x00ffU) << 8) | \
      (((__u16)(x) & (__u16)0xff00U) >> 8) ))

      -----------___constant_swab32()-----------------------
      #define ___constant_swab32(x) \
      ((__u32)( \
      (((__u32)(x) & (__u32)0x000000ffUL) << 24) | \
      (((__u32)(x) & (__u32)0x0000ff00UL) << 8) | \
      (((__u32)(x) & (__u32)0x00ff0000UL) >> 8) | \
      (((__u32)(x) & (__u32)0xff000000UL) >> 24) ))
      ------------___constant_swab64()---------------------
      #define ___constant_swab64(x) \
      ((__u64)( \
      (__u64)(((__u64)(x) & (__u64)0x00000000000000ffULL) << 56) | \
      (__u64)(((__u64)(x) & (__u64)0x000000000000ff00ULL) << 40) | \
      (__u64)(((__u64)(x) & (__u64)0x0000000000ff0000ULL) << 24) | \
      (__u64)(((__u64)(x) & (__u64)0x00000000ff000000ULL) << 8) | \
      (__u64)(((__u64)(x) & (__u64)0x000000ff00000000ULL) >> 8) | \
      (__u64)(((__u64)(x) & (__u64)0x0000ff0000000000ULL) >> 24) | \
      (__u64)(((__u64)(x) & (__u64)0x00ff000000000000ULL) >> 40) | \
      (__u64)(((__u64)(x) & (__u64)0xff00000000000000ULL) >> 56) ))
      分析:
      算法與上面的___swab16(),___swab32(),___swab64()一樣。
      只不過這里里是常量而矣。
      *****************************************************
      ------__arch__swab16()--__arch__swab16()--__arch__swab16()------
      Linux Kernel 2.6.14中的對(duì)以下的源代碼的解釋: provide defaults when no architecture-specific optimization is detected。用于無體系結(jié)構(gòu)優(yōu)化的字節(jié)交換代碼。
      #ifndef __arch__swab16
      #define __arch__swab16(x) ({ __u16 __tmp = (x) ; ___swab16(__tmp); })
      #endif

      #ifndef __arch__swab32
      #define __arch__swab32(x) ({ __u32 __tmp = (x) ; ___swab32(__tmp); })
      #endif

      #ifndef __arch__swab64
      #define __arch__swab64(x) ({ __u64 __tmp = (x) ; ___swab64(__tmp); })
      #endif
      *****************************************************
      ------------------指針型的字節(jié)交換宏---------------------
      #ifndef __arch__swab16p
      #define __arch__swab16p(x) __arch__swab16(*(x))
      #endif

      #ifndef __arch__swab32p
      #define __arch__swab32p(x) __arch__swab32(*(x))
      #endif

      #ifndef __arch__swab64p
      #define __arch__swab64p(x) __arch__swab64(*(x))
      #endif
      分析同上,只是這里將x視為一個(gè)指針。
      *****************************************************
      -----------------存放字節(jié)交換結(jié)果型宏-----------------
      #ifndef __arch__swab16s
      #define __arch__swab16s(x) do { *(x) = __arch__swab16p((x)); } while (0)
      #endif

      #ifndef __arch__swab32s
      #define __arch__swab32s(x) do { *(x) = __arch__swab32p((x)); } while (0)
      #endif

      #ifndef __arch__swab64s
      #define __arch__swab64s(x) do { *(x) = __arch__swab64p((x)); } while (0)
      #endif
      分析:
      1.x為一個(gè)指針,將該指針?biāo)赶虻膬?nèi)存單元數(shù)據(jù)送入指針型的字節(jié)交換宏__arch_swab??p(),將交換后的結(jié)果又存入該指針?biāo)赶虻膬?nèi)存單元。
      *****************************************************
      ----------------__fswab16(__u16 x)-------------------------------
      static __inline__ __attribute_const__ __u16 __fswab16(__u16 x)
      {
      return __arch__swab16(x);
      }

      --------------__swab16p(const __u16 *x)-------------------------
      static __inline__ __u16 __swab16p(const __u16 *x)
      {
      return __arch__swab16p(x);
      }

      --------------------__swab16s(__u16 *addr)----------------------
      static __inline__ void __swab16s(__u16 *addr)
      {
      __arch__swab16s(addr);
      }
      分析:
      1.對(duì)比: const __u16 * 和 __u16*不同之處。查看一下前面的代碼就懂了。

      ------------------------__fswab32(__u32 x)-----------------
      {
      static __inline__ __attribute_const__ __u32 __fswab32(__u32 x)
      {
      return __arch__swab32(x);
      }

      -------------------__swab32p(const __u32 *x)----------------
      static __inline__ __u32 __swab32p(const __u32 *x)
      {
      return __arch__swab32p(x);
      }
      說明:typedef unsigned int __u32;然后在這里將const__u32*進(jìn)行組合使用。前面已經(jīng)說明,typedef 不能組合使用。這里,將const 與typedef組合運(yùn)用,自己好好注意這一個(gè)細(xì)節(jié)。

      -------------------------__swab32s(__u32 *addr)-----------------
      static __inline__ void __swab32s(__u32 *addr)
      {
      __arch__swab32s(addr);
      }

      #if defined(__KERNEL__)
      ... ...
      #define swab16p __swab16p
      #define swab32p __swab32p
      #define swab64p __swab64p
      #define swab16s __swab16s
      #define swab32s __swab32s
      #define swab64s __swab64s
      #endif

      對(duì)const的解釋:
      1.對(duì)const的討論:
      1-1.
      const int a=1;
      a++;-------------->錯(cuò),a定義為一個(gè)常量了,所以a值不能改變。
      1-2.
      int a=0;
      const int *p = &a;
      (*p)=1;------------>error,const修飾p所指向的對(duì)象,所以(*p)值不能改變。
      1-3.
      int a=0,b=1;
      int * const p=&a;
      (*p)=1;----------->Ok
      p=&b;------------->Error
      此處const修飾p,p所指向的值可以改變,但p自身的值不能被改變。
      1-4.
      int a=0,b=1;
      const int * const p=&a;
      (*p)=1;----------->error
      p=&b;------------->Error
      這里有兩個(gè)const,一個(gè)修飾指針p,另一個(gè)修飾p所指向的int值。

      2.對(duì)const的應(yīng)用
      在函數(shù)的參數(shù)中,如果我們希望函數(shù)只能引用指針?biāo)赶虻膬?nèi)容,而不能改變其,這時(shí)可動(dòng)用const
      比如:
      int memcpy(const void *s1,const void *s2,size_t n);
      s1,s2所指向的內(nèi)容只能讀取,而不能被修改。若程序員不小心修改了其值,編譯器會(huì)報(bào)錯(cuò)。

      3.比較c++和c對(duì)const用法的不同之處:
      3-1.c++能夠把已用常量賦值的const變量看作編譯時(shí)期的常數(shù),c沒有這種功能。
      如:
      const int BUFSIZE = 1024;
      char buf[BUFSIZE];---------->Valid in C++ but illegal in C
      3-2.c++默認(rèn)const變量的鏈接性質(zhì)為內(nèi)部的,而c則相反,默認(rèn)是外部的。
      const int a=0;
      int main(){}
      在c中,a為外部的鏈接,即其他的文件在代碼 能夠訪問到它。而在c++中,a就默認(rèn)為內(nèi)部的鏈接,除非加上extern修飾詞,否則其它的文件是看不到const變量a的。
      3-3.c只能允許用常量來初始化const外部變量,c++則沒有這種限制。
      int f(void)
      const int a=f();--------->Valid in C++,but illegal in c
      int main()

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多