加载中…
个人资料
一只老虎
一只老虎
  • 博客等级:
  • 博客积分:0
  • 博客访问:9,851
  • 关注人气:39
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

浅析gcc内嵌汇编

(2007-08-07 13:32:07)
分类: 计算机知识启蒙
     在Linux代码中很多地方都使用了这种形式的汇编语言,嵌入汇编程序的格式如下:
__asm__ __volatile__ (
asm statements
: outputs
: inputs
: registers-modified
);
 asm statements是一组AT&T格式的汇编语言语句,每个语句一行,由\n分隔各行。所有的语句都被包裹在一对双引号内。其中使用的寄存器前面要加两个%%做前缀;转移指令多是局部转移,因此多使用数字标号。
 inputs指明程序的输入参数,每个输入参数都括在一对圆括号内,各参数用逗号分开。每个参数前加一个用双引号括起来的标志,告诉编译器把该参数装入到何处。
 可用的标志有:
 “g”:让编译器决定如何装入它;
 “a”:装入到ax/eax;
 “b”:装入到bx/ebx;
 “c”:装入到cx/ecx;
 “d”:装入到dx/edx;
 “D”:装入到di/edi;
 “S”:装入到si/esi;
 “q”:a、b、c、d寄存器等;
 “r”:任一通用寄存器;
 “i”:整立即数;
 “p”:有效内存地址;
 “=”:输出;
 “+”:既是输入又是输出;
 “&”:改变其值之前写;
 “%”:与下一个操作数之间可互换;
 “#”:忽略其后的字符,直到逗号;
 “*”:当优先选择寄存器时,忽略下面的字符;
 “0~9”:指定一个操作数,它既做输入又做输出。通常用“g”。
 outputs指明程序的输出位置,通常是变量。每个输出变量都括在一对圆括号内,各个输出变量间用逗号隔开。每个输出变量前加一个标志,告诉编译器从何处输出。
 可用的标志与输入参数用的标志相同,只是前面加“=”。如“=g”。输出操作数必须是左值,而且必须是只写的。如果一个操作数即做输出又做输入,那么必须将它们分开:一个只写操作数,一个输入操作数。输入操作数前加一个数字限制(0~9),指出输出操作数的序号,告诉编译器它们必须在同一个物理位置。两个操作数可以是同一个表达式,也可以是不同的表达式。
 registers-modified告诉编译器程序中将要修改的寄存器。每个寄存器都用双引号括起来,并用逗号隔开。如“ax”。如果汇编程序中引用了某个特定的硬件寄存器,就应该在此处列出这些寄存器,以告诉编译器这些寄存器的值被改变了。如果汇编程序中用某种不可预测的方式修改了内存,应该在此处加上“memory”。这样以来,在整个汇编程序中,编译器就不会把它的值缓存在寄存器中了。
 __volatile__是可选的,它防止编译器修改该段汇编语句(重排序、重组、删除等)。
 输入参数和输出变量按顺序编号,先输出后输入,编号从0开始。程序中用编号代表输入参数和输出变量(加%做前缀)。
输入、输出、寄存器部分都可有可无。如有,顺序不能变;如无,应保留“:”,除非不引起二意性。
看一个在C语言中使用at&t的嵌入汇编程序的例子,c语言中的3个int变量,一般会是三个内存地址。每个操作数的长度则要根据操作系统和编译器来决定,一般32位操作系统为32位,则每个操作数占用4个字节:
 int i=0, j=1, k=0;
 __asm__ __volatile__("
  pushl %%eax\n               //asm statement
  movl %1, %%eax\n            //asm statement
  addl %2, %%eax\n            //asm statement
  movl %%eax, %0\n            //...
  popl %%eax"                 //...
 : "=g" (k)                   //outputs                                                   
 : "g" (i), "g" (j)           //inputs
 : "ax", "memory"             //registers modified
 );   
按照参数编号原则输出参数参数k为%0,输入参数i和j依次为%1和%2。值得注意的是输出和输入标志都使用了"g",所以我们不必关心这些参数究竟是使用了寄存器还是内存操作数,编译器自己会决定。

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有