今天写内核代码时要写一个比较两个页框(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;
}