哎,还是上学期翻译的呢 x86平台,linux下内嵌汇编,,翻译的很烂

翻译 2005年05月12日 22:24:00

x86平台,linux下内嵌汇编

Bharata B. Rao (rbharata@in.ibm.com)
IBM Linux Technology Center, IBM Software Labs, India
March 2001

如果你是个linux的内核开发人员的话,你发现你会经常编写一些和系统结构有关的函数或者经常优化一段代码,你会经常用在c语言环境下内嵌一段汇编语言.让我们来看看linux下内嵌汇编的用法

简要说下GNU汇编编译器的语法
GCC,linux下的GNU c编译器,用的是AT&T的语法,下面列出一些,但并不是全部,,只是和内嵌汇编相关的部分

寄存器的命名
在寄存器的名字前加前缀%, 比如你要用eAx,那就要这样用%eAx

源操作数与目的操作数的顺序
源操作数在前,目的操作数在后,这点和Intel 语法刚好相反
比如: mov %eAx,%ebx  表示把eAx中的内容传到ebx中

操作数的大小
指令带后缀b,w,l,取决于操作数是byte,word还是long.这并不是强制的,,GCC会同过读操作数来判断后缀是什么,,但自己加上后缀没啥不好的,可以增加程序的可读性,且可减少编译器猜错的可能
movb %Al,%bl 传送byte
movw %Ax,%bx 传送word
movl %eAx,%ebx 传送longword

立即数
立即数前要加$
movl $0xffff,%eAx  将会把值0xffff送到eAx中

间接寄存器寻址
用到寄存器间接寻址内存的时候用()
movb (%esi),%Al 将把esi指向的内存单元的一个byte送到Al中

内嵌汇编
GCC提供结构(construct)"Asm"(注意第一个字母是小写:) 用来表示内嵌汇编,如下面的格式
  Asm( 汇编器模板(Assembler templAte)
     : 输出操作数 可选
     : 输入操作数 可选
     : 占用的寄存器 可选
     );
在这个样子里,汇编器模板包含汇编指令,输入操作数是变量,被用做汇编指令的输入操作数,输出操作数也是变量,被用做汇编指令的输出操作数(保存输出结果)

内嵌汇编重要的一点是它可以操作并且显式的输出到变量,由于这个特点,,"Asm"被当作是c语言同汇编语言接口

//一个基本但重要的区别是简单内嵌汇编只包含指令,而扩展内嵌汇编包含操作数,举例:

基本的内嵌汇编
{
    int A=10,b;
    Asm("movl %1, %%eAx;
  movl %%eAx, %0;"
    :"=r"(b) /*输出*/
    :"r"(A) /*输入*/
    :"%eAx" /*占用的寄存器*/
}
在这个例子里,我们用汇编指令让b的值等于A,注意以下几点:
  "b"是输出操作数,用%0来指定,"A"是输入操作数,用%1来指定
  "r"是一个操作数的限制参数(constrAint),它指定变量"A"和"b"被储存在积存器里,,输出操作数的限制参数前面有"=",,来表示他是输出操作数
  要在内嵌汇编里用寄存器"%eAx"的话,必须再多加一个%,既%%eAx,内嵌汇编用%0,%1来指定变量,任何以%开头的都将被作为输入输出操作数而不是寄存器
  第3个冒号后的"%eAx"告诉GCC,%eAx寄存器在Asm里已经被指定了,,GCC不会再用这个寄存器来储存其他值了
  movl %1, %%eAx 把"A"的值移到 %eAx中,movl %%eAx, %0 把%eAx的内容移到"b"中
  当这段Asm完成后,"b"将反映出值的变化,因为它是作为一个输出操作数,换句话说,"b"的值在Asm中改变,在Asm外表现出来

现在来仔细说说

汇编器模板
汇编器模板是一些被插入到c程序里的汇编指令(一条或多条),每一条指令要被双引号括起来,或者一组指令被一队双引号括起来,每条指令都要以分割符结束,可用的分割符可以是"/n",或者是";",操作数按顺序被编号%0,%1....

如果你不想让编译器来优化你的汇编代码,你可以用"volAtile"关键字,把它放在"Asm"的后面,,如果你的程序想和ANSI兼容,要用__Asm__ 和 __volAtile__来代替 Asm 和 volAtile

c语言的变量可以直接被内嵌汇编操作,这样非常方便

每个操作数用一个用双引号括起来的限制参数,后跟用括号扩起来的变量来定义,就是这种形式:"限制参数"(c变量)  限制参数的主要作用是用来决定操作数的寻址模式(Addressing mode)

你可以在输入和输出里用多个操作数,,每个用逗号隔开

占用的寄存器
如果在内嵌的指令中用道了寄存器,,我们可以告诉GCC,这样GCC会把我们指定的寄存器留出来不做其他的用途,但当操作数的限制参数里指明的,就不用再说了,,如"=b"(变量)
然而当指令要用到其他寄存器的时候,显式的或隐式的(并且这些寄存器并没有在输入或输出列表里出现过),这时候就要明确写在寄存器列表里的,列表列在第3个冒号后面,用寄存器的名字指定

As far as keywords are concerned, if the instructions modify the memory in some unpredictable fashion, and not
explicitly, then the "memory" keyword may be added to the list of clobbered registers. This tells GCC not to keep the
memory values cached in the register across the instructions.(这段没见过用法,就先列这儿吧 :( )

操作数的限制参数
限制参数可以有下面的作用
  操作数是否允许放在一个寄存器里,放到哪个寄存器里
  操作数是否是一个内存地址
  操作数是否是一个立即数

下面是限制参数的几种常用的用法: 
 Asm ("movl %%cr3 ,%0/n" :"=r"(cr3vAl));
表示将变量cr3vAl放到寄存器中,把%cr3中值复制先到那个寄存器,然后再把寄存器中的值更新到内存中保存变量cr3vAl的地方.由于是"=r",GCC可以把变量cr3vAl放到任何一个通用寄存器中,,如果要指定寄存器的话,用下面的方法指定
A  %eAx
b  %ebx
c  %ecx
d  %edx
S  %esi
D  %edi
用的时候就像这样 Asm ("movl %%cr3 ,%0/n" :"=b"(cr3vAl));  指定%ebx

Memory operAnd constrAint(m)
当操作数在内存中,任何操作直接作用在内存中,,不通过寄存器..通过寄存器的那种一般用在必须要用的指令或者用来使程序运行的更快,
("sidt %0/n" : :"m"(loc)); 表示输入变量loc不通过寄存器

MAthing(Digit) constrAints
当一个变量在输入输出时都用到的时候 "0","1","2".....(我想是这样吧)
Asm ("incl %0" :"=A"(vAr):"0"(vAr));
先把vAr存入寄存器%eAx,在寄存器里加1后送到vAr里

一些普通的内嵌汇编的用法
int mAin(void)
{
 int x = 10,y;
 Asm("movl %1, %%eAx;
      movl %%eAx, %0;"
  :"=r"(y)  输出变量
  :"r"(x)   输入变量
  :"%eAx");
}
在这里,,x的值被复制给y,,,x,y都先被放进寄存器里,汇编代码将会是这样:
mAin:
 pushl %ebp
 movl %esp,%ebp
 subl $8,%esp
 movl $10,-4(%ebp)
 movl -4(%ebp),%edx   /*x=10 被存在%edx里*/
#APP /*Asm stArts here*/
 movl %edx, %eAx   /*x 被移动到 %eAx*/
 movl %eAx, %edx  /*y 被分到edx*/
#NO_APP /*Asm ends here*/
 movl %edx, -8(%ebp)  /*栈中的y被edx中值更新*/

GCC 在这里任意分配寄存器,因为是"r",在我们的例子里它选%edx来储存x,读完%edx中x的值,GCC把%edx又分给了y

后面好象还有一点,,,,

还在吐槽翻译的外版书质量差吗?谈谈我个人的理解

很难想象哪个学习计算机技术的人是没看过这方面书籍的,如果只是在网上看看技术贴,那样得来的知识绝对是离散的,不系统的。而要真正学好一门学问(比如一门计算机语言或者一门技术),一本好书的作用是不言而喻的。...
  • baimafujinji
  • baimafujinji
  • 2015年11月12日 21:14
  • 5868

基于统计的开源翻译系统介绍

到目前为止,多个开源的SMT系统已经开发出来,在完成许多翻译任务中有着先进惊人的性能,如中国的英语和阿拉伯语的英文翻译。这些系统中的一些重点使用基于短语的模型(如摩西),且多年来已经已被广泛用于社区,...
  • yaoqiang2011
  • yaoqiang2011
  • 2013年08月20日 17:09
  • 3160

使用file查看可执行文件的平台性,x86 or arm ?

  • shell_albert
  • shell_albert
  • 2015年05月13日 10:50
  • 1174

黄仁宇《黄河青山》读后感

         说来挺有趣的。话说我们公司的老板读书不多吧,还老是有人问他推荐一些书籍。两年前每有人问,他就只会推荐《明朝那些事》。最近好像不知从何处觅得,居然多推荐一本《万历十五年》。我不禁感慨,...
  • xumm123
  • xumm123
  • 2011年06月18日 17:29
  • 5375

火狐上好用的翻译插件

一键应用 以下是它的链接 http://mozilla.com.cn/thread-30396-1-1.html小诺:虽然这个不止有翻译功能,但它这方面的强大还是比较突出的,相对于其他翻译插件来说...
  • xiaonuo911teamo
  • xiaonuo911teamo
  • 2017年08月02日 18:32
  • 2463

KVM基于X86硬件辅助的虚拟化技术实现机制

TAG标签: x86 虚拟化技术 KVM 硬件辅助 实现机制 摘要:本系列(两部分)文章以 AMD 的硬件平台为例,介绍 KVM 基于 X86 硬件辅助的虚拟化技术的实现机制, 力图让读者对 KVM ...
  • u013484974
  • u013484974
  • 2014年02月14日 15:07
  • 1501

Ubuntu实现划词翻译

Ubuntu实现划词翻译
  • x_r_su
  • x_r_su
  • 2016年11月03日 18:09
  • 844

使用OmegaT进行翻译的步骤

软件包:OmegaT_2.5.0_04_Beta_Windows.exe和OmegaT-tokenizers_0.4_2-2.1.zip,均下载自OmegaT的官网。如果上不去http://www.o...
  • laurawang2011
  • laurawang2011
  • 2011年12月02日 17:58
  • 2495

Qt:QML生成翻译中间文件ts

在.pro文件中加入这段代码就可以生成翻译中间文件tsTRANSLATIONS+=zh_CN.ts en_us.tsc++代码中需要翻译的文字需要用tr包住,qml需要翻译的文字需要qsTr包住tr(...
  • x356982611
  • x356982611
  • 2016年10月25日 10:53
  • 741

网贴翻译 聆听国外的声音

世界说中国  网贴翻译  聆听国外的声音 龙腾网 - 倾听各国草根真实声音,纵论全球平民眼中世界...
  • yue31313
  • yue31313
  • 2017年03月16日 23:28
  • 268
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:哎,还是上学期翻译的呢 x86平台,linux下内嵌汇编,,翻译的很烂
举报原因:
原因补充:

(最多只允许输入30个字)