Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1357353
  • 博文数量: 281
  • 博客积分: 8800
  • 博客等级: 中将
  • 技术积分: 3346
  • 用 户 组: 普通用户
  • 注册时间: 2006-05-17 22:31
文章分类

全部博文(281)

文章存档

2013年(1)

2012年(18)

2011年(16)

2010年(44)

2009年(86)

2008年(41)

2007年(10)

2006年(65)

我的朋友

分类: C/C++

2007-08-30 22:30:27

1.简介
本文介绍在c代码中嵌入汇编语言的方法,所有的方法仅对gcc(Gnu C Compiler)有效。由于作者是在一台pc上进行的实验,所以例子中如果未加说明,所有的汇编代码均为x86汇编。本文的唯一参考资料就是gcc Manual,其中的5.36小节介绍了在c中嵌入汇编的办法。
2.如何在c中嵌入汇编代码
2.1.最简单的情形
在gcc里有一个asm表达式,用于实现嵌入汇编。就像这样
asm("xor %%eax, %%eax");
这个汇编指令的作用是吧eax寄存器清零,你也许注意到这些代码和我们常见的x86汇编代码有些不同,的确,gcc使用的汇编格式是AT&T格式而不是DOS下常见的Intel格式,它们之间主要区别有:AT&T格式的寄存器使用%标志开头,例如Intel格式中的EAX在这里写作%eax;AT&T格式的目的操作数是后一个而不像Intel格式那样是前一个,比如:
asm("movl %%eax, %%ebx");
是将eax寄存器的值移到ebx。另外还有一些区别,比如内存地址的表示方法等等,详情可以参考DJGPP FAQ里的Coverting between Intel ASM syntax and AT&T syntax。
另外还要注意%号在asm表达式里是特殊字符,所以%eax前面要再加一个%号进行转义,这样就成了"%%eax"这样的寄存器表示方法,如果你用的是Sparc之类的cpu,寄存器使用"r1""r5"之类的表达式,就不需要累赘的%号了。
为了比较易读,多行的汇编代码可以写成这样
asm("xor %%eax, %%eax
movl -20(%%ebp), %%ebx
sub %%ebx, %%eax");
不过在最新的gcc-3系列里一个字符串写了一行以上是会引发一个warning的,让人看了不舒服,这样写就不会了:
asm("xor %%eax, %%eax \n\t"
"movl -20(%%ebp), %%ebx \n\t"
"sub %%ebx, %%eax");
\n就是换行,\t是tab对齐,这下明白了吧 :)
2.2.使用c中定义的变量
先给出一个例子:
int foo;
asm("movl %%eax, %0"
: "=g" (foo));
在asm()中,在冒号分隔符后面声明你的变量,括号中是变量名(foo),"=g"表示这是一个作为输出的整型变量,如果变量是作为输入的话,就要放在第二个括号分隔符后面,象这样:
int foo1,foo2;
asm("movl %1, %%eax \n\t"
"movl %%eax, %0"
: "=g" (foo1)
: "g" (foo2));
程序是把foo2的内容赋给foo1。从这个例子可以看到,变量在汇编语言里被引用的时候表示符是该变量在asm()里被声明的位置,foo1在asm()里首先声明,所以是%0,foo2紧接着所以是%1。"g"表示是一个整型,前面有"="号说明这是一个作为输出的变量(也就是被写的),没有"="号就说明是作为输入的变量。别的被支持的类型还有"r"(寄存器变量),"m"(内存变量),"f"(浮点变量)等等,更多的表示可以参考gcc manual 20.7.1 。
2.3.避免寄存器冲突
如果你在汇编中显式的使用寄存器,编译器会注意不会在上下文中造成冲突,但是有一些指令是不会显式的使用寄存器的,例如cpuid这条指令,它运行以后会改变%eax,%ebx,%ecx,%edx的值,但是这些寄存器不会在代码里出现,因此编译器不会为你避开这个冲突,如果你直接调用这个指令,可能就会造成你的代码core dump!一个笨笨的办法是自己保护寄存器,调用cpuid之前先将四个寄存器push到栈里,运行了cpuid之后将值保存,再pop这四个寄存器。当然这样很影响代码的效率。其实解决的办法很简单,在asm()的第三个冒号后面声明那些需要保护的寄存器就可以了,像这样:
asm("cpuid"
:
:
:"%eax","%ebx","%ecx","%edx");
注意在这里一个"%"号就好了,这样编译器就会小心的避开这些寄存器的冲突
阅读(1684) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~