手机站
网通分站
电信主站
密 码:
用户名:
当前位置 : 主页>网站运营>建站经验>列表

Linux 汇编语言研发指南 AT

来源:互联网 作者:west263.com 时间:2008-04-16
西部数码-全国虚拟主机10强!40余项虚拟主机管理功能,全国领先!双线多线虚拟主机南北访问畅通无阻!免费赠送企业邮局,.CN域名,自助建站480元起,免费试用7天,满意再付款! P4主机租用799元/月.月付免压金!

例如:



__asm__("nop"); 


假如需要同时执行多条汇编语句,则应该用"\n\t"将各个语句分隔开,例如:



__asm__( "pushl %陎 \n\t"

         "movl , %陎 \n\t"

         "popl 陎");


通常嵌入到 C 代码中的汇编语句很难做到和其他部分没有任何关系,因此更多时候需要用到完整的内联汇编格式:



__asm__("asm statements" : outputs : inputs : registers-modified);




插入到 C 代码中的汇编语句是以":"分隔的四个部分,其中第一部分就是汇编代码本身,通常称为指令部,其格式和在汇编语言中使用的格式基本相同。指令部分是必须的,而其他部分则能够根据实际情况而省略。

在将汇编语句嵌入到C代码中时,操作数如何和C代码中的变量相结合是个很大的问题。GCC采用如下方法来解决这个问题:程式员提供具体的指令,而对寄存器的使用则只需给出"样板"和约束条件就能够了,具体如何将寄存器和变量结合起来完全由GCC和GAS来负责。

在GCC内联汇编语句的指令部中,加上前缀'%'的数字(如%0,%1)表示的就是需要使用寄存器的"样板"操作数。指令部中使用了几个样板操作数,就表明有几个变量需要和寄存器相结合,这样GCC和GAS在编译和汇编时会根据后面给定的约束条件进行恰当的处理。由于样板操作数也使用' %'作为前缀,因此在涉及到具体的寄存器时,寄存器名前面应该加上两个'%',以免产生混淆。

紧跟在指令部后面的是输出部,是规定输出变量如何和样板操作数进行结合的条件,每个条件称为一个"约束",必要时能够包含多个约束,相互之间用逗号分隔开就能够了。每个输出约束都以'='号开始,然后紧跟一个对操作数类型进行说明的字后,最后是如何和变量相结合的约束。凡是和输出部中说明的操作数相结合的寄存器或操作数本身,在执行完嵌入的汇编代码后均不保留执行之前的内容,这是GCC在调度寄存器时所使用的依据。

输出部后面是输入部,输入约束的格式和输出约束相似,但不带'='号。假如一个输入约束需要使用寄存器,则GCC在预处理时就会为之分配一个寄存器,并插入必要的指令将操作数装入该寄存器。和输入部中说明的操作数结合的寄存器或操作数本身,在执行完嵌入的汇编代码后也不保留执行之前的内容。

有时在进行某些操作时,除了要用到进行数据输入和输出的寄存器外,还要使用多个寄存器来保存中间计算结果,这样就难免会破坏原有寄存器的内容。在GCC内联汇编格式中的最后一个部分中,能够对将产生副作用的寄存器进行说明,以便GCC能够采用相应的措施。

下面是个内联汇编的简单例子:

例4.内联汇编



/* inline.c */



int main()

{

    int a = 10, b = 0;



    __asm__ __volatile__("movl %1, %陎;\n\r"

                         "movl %陎, %0;"

                         :"=r"(b)      /* 输出 */    

                         :"r"(a)       /* 输入 */

                         :"陎");     /* 不受影响的寄存器 */

    

    printf("Result: %d, %d\n", a, b);

}


上面的程式完成将变量a的值赋予变量b,有几点需要说明:

  • 变量b是输出操作数,通过%0来引用,而变量a是输入操作数,通过%1来引用。
  • 输入操作数和输出操作数都使用r进行约束,表示将变量a和变量b存储在寄存器中。输入约束和输出约束的不同点在于输出约束多一个约束修饰符'='。
  • 在内联汇编语句中使用寄存器eax时,寄存器名前应该加两个'%',即%陎。内联汇编中使用%0、%1等来标识变量,任何只带一个'%'的标识符都看成是操作数,而不是寄存器。
  • 内联汇编语句的最后一个部分告诉GCC他将改变寄存器eax中的值,GCC在处理时不应使用该寄存器来存储任何其他的值。
  • 由于变量b被指定成输出操作数,当内联汇编语句执行完毕后,他所保存的值将被更新。

在内联汇编中用到的操作数从输出部的第一个约束开始编号,序号从0开始,每个约束记数一次,指令部要引用这些操作数时,只需在序号前加上'%'作为前缀就能够了。需要注意的是,内联汇编语句的指令部在引用一个操作数时总是将其作为32位的长字使用,但实际情况可能需要的是字或字节,因此应该在约束中指明正确的限定符:

限定符意义
"m"、"v"、"o"内存单元
"r"任何寄存器
"q"寄存器eax、ebx、ecx、edx之一
"i"、"h"直接操作数
"E"和"F"浮点数
"g"任意
"a"、"b"、"c"、"d"分别表示寄存器eax、ebx、ecx和edx
"S"和"D"

文章整理:西部数码--专业提供域名注册虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!