一句话说清楚c代码中如何内嵌汇编

一言以蔽之, 用汇编模板表示函数实现,输出和输入表示参数,%0, %1 表示输出、输入所修饰部分的编号,同时描述C 参数与汇编寄存器的关系。

内嵌汇编语法如下:

_asm_ _volatile_ (
                          汇编语句模板:
                          输出部分:
                          输入部分:
                          破坏描述部分
)

下面通过一个简单的例子来熟悉内嵌汇编的语法规则。

max@ubuntu:~$ cat add.c
#include <stdio.h>

int main()
{
	/* val1+val2=val3 */
	unsigned int val1 = 1;
	unsigned int val2 = 2;
	unsigned int val3 = 0;

	printf("val1:%d, val2:%d,val3:%d\n", val1, val2, val3);

	asm volatile(
			"movl $0, %%eax\n\t" /* clear %eax to 0*/
			"addl %1, %%eax\n\t" /* %eax += val1 */
			"addl %2, %%eax\n\t" /* %eax += val2 */
			"movl %%eax, %0\n\t" /* val2 = %eax*/
			: "=m" (val3) /* output =m mean only write output 
					 memory variable*/
			: "c" (val1), "d" (val2) /* input c or d %ecx/%edx*/
		    );
	printf("val1:%d+val2:%d=val3:%d\n", val1, val2,val3);
	return 0;
}
max@ubuntu:~$ 

 

这个例子是用汇编代码实现val3 = val1 + val2 的功能,我们具体来看其中涉及的语法规则。

_asm 是GCC 关键字asm 的宏定义,是内嵌汇编的关键字,表示这是一条内嵌汇编语句。 

_volatile 是GCC 关键字volatile的宏定义,告诉编译器不要优化代码,汇编指令保留原样

 

    内嵌汇编关键字asm volatile 的括号内部第一部分是汇编代码,这里的汇编代码和之前学习的汇编代码有一点点差异,体现在%转义符号。寄存器前面多一个%的转义符号,有两个%, 而%加一个数字则表示第二部分输出、第三部分输入以及第四部分存坏描述的编号。

   上述内嵌汇编范例中定义了3个变量val1, val2 和val3 , 希望求解val3 = val1 + val2, 下面具体分析.

 第一行  “movl $0, %%eax" 是把EAX清0.

 第二行  "addl %1, %%eax", %1 是指下面的输出和输入的部分,第一个输出编号为%0, 第二个为%1, 第三个为%2。 %1是指val1, 前面一个“c"是指用ECX寄存器存储val1的值,这样编译器在编译时就自动把val1的值放到ECX里面。%1实际上就是把ECX的值与EAX 寄存器求和然后放到EAX寄存器中,本例中由于EAX为0,所以结果就是ECX的值放放了EAX寄存器。

 第三行 “addl %2, %%eax", %2 是指val2存在EDX寄存器,就是把val1的值加上val2的值再放到EAX里。

 最后一条指令“movl %%eax, %0" 是把val2 加上val2的值存储的地方放到%0, %0就是val3, 我们这里用=m 修饰,它的意思就是写到内存变量里面去,m就是内存memory, 不是使用寄存器了,这条指令是直接把变量放到内存val3里面。

至此, 这段代码就实现了val3 = val1 + val2的功能。

简单总结一下,如果把内嵌汇编当作一个函数,则第二部分输出和第三部分输入相当于函数的参数和返回值,而第一部分的汇编代码则相当于函数内部的具体代码。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值