内联汇编

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 alregister

2内联汇编

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" 外反映出来。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值