当前位置:操作系统 > Unix/Linux >>

Linux操作系统中x86的内联汇编

Linux 中 x86 的内联汇编

  将各个部分组合起来

  developerWorks

  文档选项

  将此页作为电子邮件发送

  最新推荐

  Java 应用开发源动力 - 下载免费软件,快速启动开发

  级别: 初级

  Bharata B. RaoIBM Linux 技术中心,IBM 软件实验室,印度

  Bharata B. Rao 提供了在 Linux 平台上使用和构造 x86 内联汇编的概括性介绍。他介绍了内联汇编及其各种用法的基础知识,提供了一些基本的内联汇编编码指导,并解释了在 Linux 内核中内联汇编代码的一些实例。

  如果您是 Linux 内核的开发人员,您会发现自己经常要对与体系结构高度相关的功能进行编码或优化代码路径。您很可能是通过将汇编语言指令插入到 C 语句的中间(又称为内联汇编的一种方法)来执行这些任务的。让我们看一下 Linux 中内联汇编的特定用法。(我们将讨论限制在 IA32 汇编。)

  GNU 汇编程序简述

  让我们首先看一下 Linux 中使用的基本汇编程序语法。GCC(用于 Linux 的 GNU C 编译器)使用 AT&T 汇编语法。下面列出了这种语法的一些基本规则。(该列表肯定不完整;只包括了与内联汇编相关的那些规则。)

  寄存器命名

  寄存器名称有 % 前缀。即,如果必须使用 eax,它应该用作 %eax.

  源操作数和目的操作数的顺序

  在所有指令中,先是源操作数,然后才是目的操作数。这与将源操作数放在目的操作数之后的 Intel 语法不同。

  mov %eax, %ebx, transfers the contents of eax to ebx.

  作数大小

  根据操作数是字节 (byte)、字 (word) 还是长型 (long),指令的后缀可以是 b、w 或 l.这并不是强制性的;GCC 会尝试通过读取操作数来提供相应的后缀。但手工指定后缀可以改善代码的可读性,并可以消除编译器猜测不正确的可能性。

  movb %al, %bl ―― Byte move

  movw %ax, %bx ―― Word move

  movl %eax, %ebx ―― Longword move

  立即操作数

  通过使用 $ 指定直接操作数。

  movl $0xffff, %eax ―― will move the value of 0xffff into eax register.

  间接内存引用

  任何对内存的间接引用都是通过使用 ( ) 来完成的。

  movb (%esi), %al ―― will transfer the byte in the memory

  pointed by esi into al

  register

  内联汇编

  GCC 为内联汇编提供特殊结构,它具有以下格式:

  GCG 的 "asm" 结构

  asm ( assembler template

  : output operands (optional)

  : input operands (optional)

  : list of clobbered registers

  (optional)

  );

  本例中,汇编程序模板由汇编指令组成。输入操作数是充当指令输入操作数使用的 C 表达式。输出操作数是将对其执行汇编指令输出的 C 表达式。

  内联汇编的重要性体现在它能够灵活操作,而且可以使其输出通过 C 变量显示出来。因为它具有这种能力,所以 "asm" 可以用作汇编指令和包含它的 C 程序之间的接口。

  一个非常基本但很重要的区别在于 简单内联汇编只包括指令,而 扩展内联汇编包括操作数。要说明这一点,考虑以下示例:

  内联汇编的基本要素

  {

  int a=10, b;

  asm ("movl %1, %%eax;

  movl %%eax, %0;"

  :"=r"(b) /* output */

  :"r"(a) /* input */

  :"%eax"); /* clobbered register */

  }

  在上例中,我们使用汇编指令使 "b" 的值等于 "a".请注意以下几点:

  * "b" 是输出操作数,由 %0 引用,"a" 是输入操作数,由 %1 引用。

  * "r" 是操作数的约束,它指定将变量 "a" 和 "b" 存储在寄存器中。请注意,输出操作数约束应该带有一个约束修饰符 "=",指定它是输出操作数。

  * 要在 "asm" 内使用寄存器 %eax,%eax 的前面应该再加一个 %,换句话说就是 %%eax,因为 "asm" 使用 %0、%1 等来标识变量。任何带有一个 % 的数都看作是输入/输出操作数,而不认为是寄存器。

  * 第三个冒号后的修饰寄存器 %eax 告诉将在 "asm" 中修改 GCC %eax 的值,这样 GCC 就不使用该寄存器存储任何其它的值。

  * movl %1, %%eax 将 "a" 的值移到 %eax 中, movl %%eax, %0 将 %eax 的内容移到 "b" 中。

  * 因为 "b" 被指定成输出操作数,因此当 "asm" 的执行完成后,它将反映出更新的值。换句话说,对 "asm" 内 "b" 所做的更改将在 "asm" 外反映出来。

  

上一个:虚拟化帮你找回失去的资源
下一个:JFFS2文件系统及新特性介绍

更多Unix/Linux疑问解答:
路由原理介绍
子网掩码快速算法
改变网络接口的速度和协商方式的工具miitool和ethtool
Loopback口的作用汇总
OSPF的童话
增强的ACL修改功能
三层交换机和路由器的比较
用三层交换机组建校园网
4到7层交换识别内容
SPARC中如何安装Linux系统(2)
SPARC中如何安装Linux系统(1)
用Swatch做Linux日志分析
实战多种Linux操作系统共存
浅析Linux系统帐户的管理和审计
Linux2.6对新型CPU的支持(2)
电脑通通透
玩转网络
IE/注册表
DOS/Win9x
Windows Xp
Windows 2000
Windows 2003
Windows Vista
Windows 2008
Windows7
Unix/Linux
苹果机Mac OS
windows8
安卓/Android
Windows10
如果你遇到操作系统难题:
请访问www.zzzyk.com 试试
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,