linux printk 源码,Printk原理简介
可變參數操作宏
假設有一段代碼如程序清單 1.3所示:
程序清單?1.3
int printk(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
i=vsprintf(buf,fmt,args);
va_end(args);
}
va_list類型的定義如程序清單 1.4所示,可見va_list其實就是一個char型指針。
程序清單?1.4
typedef char *va_list;
va_start宏定義如程序清單 1.5所示:
程序清單?1.5
#define __va_rounded_size(TYPE) \
(((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
#define va_start(AP, LASTARG) \
(AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG)))
AP表示argument pointer,是參數指針的意思,其實就是va_list類型變量;LASTARG表示last argument,其實就是printk的第一個參數fmt,之所以叫last argument,是因為這個參數是最后一個壓棧的。
__va_rounded_size的作用是按int類型的倍數計算TYPE變量在棧中的大小,假設TYPE變量是5字節大小,則__va_rounded_size(TYPE)值為8,因為每次壓棧的數據大小都是int類型數據大小的倍數。
(char *) &(LASTARG)表示將fmt變量的地址轉為char *指針,這樣加上__va_rounded_size (LASTARG)后的值就是第一個可變參數的地址。如圖 1.2所示:
圖?1.2 va_list args移動示意圖
由此可見,va_start宏的作用就是將指針args跳過fmt參數,指向第一個要解析的可變參數。
va_arg宏定義如程序清單 1.6所示:
程序清單?1.6
#define va_arg(AP, TYPE) \
(AP += __va_rounded_size (TYPE), \
*((TYPE *) (AP - __va_rounded_size (TYPE))))
AP += __va_rounded_size (TYPE),經過這個表達式運算后,args指向了下一個參數;
*((TYPE *) (AP - __va_rounded_size (TYPE)))表示取原來args位置處的變量值,如圖 1.3所示:
圖?1.3 va_arg作用
va_end是一個空的宏。
總結
以上是生活随笔為你收集整理的linux printk 源码,Printk原理简介的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 复制集配置文件linux,mongodb
- 下一篇: linux下usb设备节点名不固定,解决