前面介绍了很多理论性的规则,这里通过分析一个实例来加深对inline assembly的理解。
下面的代码是Linux内核i386版本中的syscall0定义:
#define _syscall0(type, name) \
type name(void) \
{ \
long __res; \
__asm__ volatile ( "int $0x80" \
: "=a" (__res) \
: "0" (__NR_##name)); \
__syscall_return(type, __res); \
}
对于系统调用fork来说,上述宏展开为:
pid_t fork(void)
{
long __res;
__asm__ volatile ( "int $0x80"
: "=a" (__res)
: "0" (__NR_fork));
__syscall_return(pid_t, __res);
}
根据前面对inline assembly语法及使用方法的说明,我们不难理解这段代码的含义。将这段内联汇编翻译更可读的伪码形式为:
pid_t fork(void)
{
long __res;
%eax = __NR_fork /* __NR_fork为内核分配给系统调用fork的调用号 */
int $0x80 /* 触发中断,内核根据%eax的值可知,引起中断的是fork system call */
__res = %eax /* 中断返回值保持在%eax中 */
__syscall_return(pid_t, __res);
}
【参考资料】
1. GCC-Inline-Assembly-HOWTO
2. Inline assembly for x86 in Linux
3. 《程序员的自我修养—链接、装载与库》,第12章
4. Using Assembly Language in Linux
=============== EOF ================