马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
插入C语言的一个汇编语言代码片段可以分成4部分,以“:”号加以分隔,其一般形式为: 指令部:输出部:输入部:损坏部 static __inline__ void atomic_add(int i, atomic_t *v) { __asm_volatile__( LOCK "addl %1, %0" : "=m" (v->counter) : "ir" (i), "m" (v->counter)); } 当汇编语言代码嵌入到C代码时,解决操作数和C代码中的变量结合是一个问题。我们无法确切知道gcc在嵌入点的前后会把哪个寄存器分配给哪个变量等,所以gcc采用一种方法:程序员只提供具体的指令,而对寄存器的使用则一般只提供一个“样板”和一些约束条件,而到底如何把变量和操作数结合的问题留给gcc和gas去处理。 指令部 数字加上前缀%,如%1、%0等,表示需要使用寄存器的样板操作数。可以使用的此类操作数的总数取决于具体CPU中通用寄存器的数量。 输出部 规定对输出变量,即目标操作数如何结合的约束条件。每个这样的条件称为一个“约束条件”。必要时输出部可以有多个约束条件,互相以逗号分隔。每个输出约束以“=”号开头,然后是一个字母表示对操作数类型的说明,然后是关于变量结合的约束。例子中: : “=m” (v->counter) 这里只有一个约束条件,“=m”表示相应的目标操作数(指令中的%0)是一个内存单元v->counter。 输入部 输入部约束的格式和输出约束相似,但不带“=”号。例子中: 第1个为"ir" (i),表示指令中的%1可以是一个在寄存器中的“直接操作数”(i表示immediate),并且该操作数来自于C代码中的变量名(这里是调用参数)i。 第2个约束条件“m” (v->counter)意义与输入约束相同。 损坏部 有些操作中,除了用于输入操作数和输出操作数的寄存器外,还要将若干个寄存器用于计算或者操作的中间结果。这样,这些寄存器原有的内容就损坏了,所以要在损坏部对操作的副作用加以说明,让gcc采取相应的措施。不过,有的时候就直接把这些说明放在输出部了,那也并无不可。 操作数的编号从输出部的第一个约束(序号为0)开始,顺序数下来,每个约束计数加1次。在指令部中引用这些操作数或分配用于这些操作数的寄存器时,就在序号前面加上%号。 表示约束条件的字母有很多,主要有: "m"、"v"和"o" ---- 表示内存单元 "r" ---- 表示任何寄存器 "q" ---- 表示寄存器eax,ebx,ecx,edx之一 "i"和"h" ---- 表示直接操作数 "E"和"F" ---- 表示浮点数 "g" ---- 表示任意 "a","b", "c" "d" ---- 分别表示要使用寄存器eax ebx ecx和edx "S"和"D" ---- 分别表示要使用寄存器esi和edi "I" ---- 表示常数(0至31) 回到上面的例子,这段代码的作用是将参数i的值加到v->counter上。代码的关键字LOCK表示在执行addl指令时要把系统总线锁住,不让别的CPU打扰,以保证原子性操作。 下面就可以照着上面的说明把下面代码看懂吧。 代码: /* 以下定义系统调用嵌入式汇编宏函数 */ /* 不带参数的系统调用宏函数。type name(void)。
* %0 -eax(__res), %1 - eax(__NR_##name)。其中name是系统调用的名称
* 与 __NR_ 组合形成上面的系统调用符号常用,从而用来对系统调用表中函数指针寻址
* 调用系统中断0x80,返回值->eax(_res), 输入为系统中断调用号__NR_name
* 返回: 如果返回值大于等于0,则返回该值,否则置出错号errno,并返回-1
*/
#define _syscall0(type, name)/
type name(void)/
{/
long __res;/
__asm__ volatile ("int $0x80" /
: "=a" (__res) /
: "" (__NR_##name));/
if (__res >= 0)/
{/
return (type)__res;/
}/
errno = -__res;/
return -1;/
} /* 有1个参数的系统调用宏函数。type name(atype a)
* %0 - eax(__res), %1 - eax(__NR_name), %2 - ebx(a)
*/
#define _syscall1(type, name, atype, a) /
type name(atype a)/
{/
long __res;/
__asm__ volatile ("int $0x80"/
: "=a" (_res)/
: "" (__NR_#name), "b" ((long)(a)));/
if (__res >= 0)/
{/
return (type)__res;/
}/
errno = -__res;/
return -1;/
} /* 有2个参数的系统调用宏函数。type name(atype a, btype b)
* %0 - eax(__res), %1 - eax(__NR_name), %2 - ebx(a), %3 - ecx(b)
*/
#define _syscall2(type, name, atype, a, btype, b)/
type name(atype a, btype b)/
{/
long __res;/
__asm__ volatile ("int $0x80"/
: "=a" (__res)/
: "" (__NR_##name), "b" ((long)(a)), "c" ((long)(b)));/
if (__res >= 0)/
{/
return (type)__res;/
}/
errno = -__res;/
return -1/
} /* 有3个参数的系统调用宏函数。type name(atype a, btype b, ctype c)
* %0 - eax(__res), %1 - eax(__NR_name), %2 - ebx(a), %3 - ecx(b), %4 - edx(c)
*/
#define _syscall3(type, name, atype, a, btype, b, ctype, c) /
type name(atype a, btype b, ctype c)/
{/
long __res;/
__asm__ volatile ("int $0x80"/
: "=a" (__res) /
: "" (__NR_##name), "b" ((long)(a)), /
"c" ((long)(b)), "d" ((long)(c)));/
if (__res >= 0)/
{/
return (type)__res;/
}/
errno = -__res;/
return -1;/
}
|