wiki:MixedCandAsm

C代码中嵌入汇编代码

gcc内嵌汇编基础知识请参考http://teamtrac.ustcsz.edu.cn/raw-attachment/wiki/MixedCandAsm/gcc%E5%86%85%E5%B5%8C%E6%B1%87%E7%BC%96.pdf

C代码中嵌入一般汇编代码的方式

#include <stdio.h>

int  main()
{
	/* val1+val2=val3 */
	unsigned int val1 = 1;
	unsigned int val2 = 2;
	unsigned int val3 = 0;
	printf("val1:%d,val2:%d,val3:%d\n",val1,val2,val3);
	asm volatile(
	"movl $0,%%eax\n\t" /* clear %eax to 0*/
	"addl %1,%%eax\n\t" /* %eax += val1 */
	"addl %2,%%eax\n\t" /* %eax += val2 */
	"movl %%eax,%0\n\t" /* val2 = %eax*/
	: "=m" (val3) /* output =m mean only write output memory variable*/
	: "c" (val1),"d" (val2) /* input c or d mean %ecx/%edx*/
	);
	printf("val1:%d+val2:%d=val3:%d\n",val1,val2,val3);

	return 0;
}

C代码中嵌入系统调用汇编代码

#include <stdio.h>
#include <time.h>

int  main()
{
	time_t tt;
	struct tm *t;
        int ret;
/*
(gdb) disassemble time
Dump of assembler code for function time:
   0x0804f800 <+0>:	push   %ebp
   0x0804f801 <+1>:	mov    %esp,%ebp
   0x0804f803 <+3>:	mov    0x8(%ebp),%edx
   0x0804f806 <+6>:	push   %ebx
   0x0804f807 <+7>:	xor    %ebx,%ebx
   0x0804f809 <+9>:	mov    $0xd,%eax
   0x0804f80e <+14>:	int    $0x80
   0x0804f810 <+16>:	test   %edx,%edx
   0x0804f812 <+18>:	je     0x804f816 <time+22>
   0x0804f814 <+20>:	mov    %eax,(%edx)
   0x0804f816 <+22>:	pop    %ebx
   0x0804f817 <+23>:	pop    %ebp
   0x0804f818 <+24>:	ret    
End of assembler dump.

*/
#if 0
	time(&tt);
	printf("tt:%ld\n",tt);
#else
        /* 没有使用常规寄存器传参的方法 */
	asm volatile(
        "mov $0,%%ebx\n\t" /* 不使用参数tt */
	"mov $0xd,%%eax\n\t" 
	"int $0x80\n\t" 
	"mov %%eax,%0\n\t"  
	: "=m" (tt) 
	);
	printf("tt:%ld\n",tt);
	t = localtime(&tt);
	printf("time:%d:%d:%d:%d:%d:%d\n",t->tm_year+1900, t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
        /* 使用常规寄存器传参的方法 */
	asm volatile(
        "mov %1,%%ebx\n\t" /* 使用参数tt */
	"mov $0xd,%%eax\n\t" 
	"int $0x80\n\t" 
	"mov %%eax,%0\n\t"  
	: "=m" (ret) 
        : "b" (&tt)
	);
	printf("tt:%ld\n",tt);
	t = localtime(&tt);
	printf("time:%d:%d:%d:%d:%d:%d\n",t->tm_year+1900, t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
#endif


	return 0;
}

从如下time函数的内核实现例程sys_time来看,当time的参数tloc为假时(没有使用ebx寄存器),使用eax返回的时间值,从上面对time的反汇编来看gcc编译器也没有使用ebx寄存器(没有遵守系统调用参数传递的一般方法)

以下代码来自linux-3.2.1\kernel\time.c line:62

/*
 * sys_time() can be implemented in user-level using
 * sys_gettimeofday().  Is this for backwards compatibility?  If so,
 * why not move it into the appropriate arch directory (for those
 * architectures that need it).
 */
SYSCALL_DEFINE1(time, time_t __user *, tloc)
{
	time_t i = get_seconds();

	if (tloc) {
		if (put_user(i,tloc))
			return -EFAULT;
	}
	force_successful_syscall_return();
	return i;
}

参考资料

Last modified 4 years ago Last modified on 05/03/13 11:05:52

Attachments (1)

Download all attachments as: .zip