GCC内联汇编写的memcmp函数 for x86-64

今天写内核代码时要写一个比较两个页框(Page Frame)的函数,想到用内联汇编来写这个功能。下面是代码:

long cmp_x64(void *s1, void *s2, size_t n)
{
    size_t num = n / 8;
    register long res;

    __asm__ __volatile__
    (
     "testq %3,%3\n\t"               ; 测试num是不是0
     "repe  cmpsq\n\t"                ; 不停地比较直到cx寄存器为0或比较到差别
     "je        1f\n\t"              ; 两块内存相等,跳出,返回0.
     "sbbq      %0,%0\n\t"    ; sbb是x86的减法指令,会额外地减去CF(借位)的值,这样%0就会是0或者-1
     "orq       $1,%0\n"         ; 把立即数1或到%0上,这样%0就会是1或者-1.
     "1:"
         : "=&a"(res)          ;  传入变量res放入寄存器ax,且这个变量是输出值(=),不要与其它输入输出共用寄存器(&)
     : "0"(res), "S"(s1), "D"(s2), "c"(num)  ; 输入列表
     : "cc");           // clobber list 告诉gcc在这段内联汇编中哪些寄存器被显式/隐式修改.If our instruction can alter the condition code register, we have to add "cc" to the list of clobbered registers.

    return res;
}

Linux内核中的宏可变参数(GCC的宏可变参数)

Linux内核中的宏可变参数(GCC的宏可变参数)。
写内核模块的时候为了调试方便,经常需要wrap一下printk函数。下面的宏定义非常有实用价值。
注意两个井号~~
记到博客里~~

#define seclvl_printk(verb, type, fmt, arg...)			\
	do {							\
		if (verbosity >= verb) {			\
			static unsigned long _prior;		\
			unsigned long _now = jiffies;		\
			if ((_now - _prior) > HZ) {		\
				printk(type "%s: %s: " fmt,	\
					MY_NAME, __FUNCTION__ ,	\
					## arg);		\
				_prior = _now;			\
			}					\
		}						\
	} while (0)