gcc内联汇编入门

本文详细介绍了GCC内联汇编的使用,从AT&T语法基础开始,涵盖源目操作符顺序、寄存器和立即数、寻址方式以及后缀修饰。接着讨论了C函数的参数传递,包括参数如何通过堆栈传递,frame pointer的作用以及如何清理参数表。最后,通过实例展示了非内联汇编和内联汇编的代码对比,揭示了内联汇编在优化代码和提高效率方面的优势。
摘要由CSDN通过智能技术生成

最近在读linux0.10内核,正好遇到了内联汇编。

gcc其中一个很强大的功能就是内联汇编。

但是苦于广大学生(包括我)都被intel语法毒害很深,结果没几个会用gcc内联汇编的了。。。

 

一开始我也看的云里雾里,但是一用gcc -S测试一下,马上就非常明白了。

所以还是实践为王。

这里就稍微从AT&T语法一直介绍到gcc内联汇编运用实例。

 

AT&T语法。

其实AT&T语法真的不难。。。看了20min大概就懂得差不多了。

推荐直接看gnu as的pdf,总共16页,而且涵盖了不少下面要将的内容。

这里只提个概要。

1.源目操作符顺序

同一条语句intel语法 MOV EAX,EBX 源在后,目在前(我自己其实很分不清源和目,只知道咋用),intel这句就是把EBX的值赋给EAX。

AT&T语法就是mov %ebx,%eax,顺序正好相反,其实个人觉得AT&T这个顺序更加直观。

 

2.寄存器,立即数

上面其实就已经有了寄存器的例子了,用寄存器的话要用%表示,否则会被解释成对应名称的内存地址

立即数同理,只不过必须用$前缀,不然表示地址。立即数方面,intel一般都是用h后缀表示16进制,而AT&T用更像C的0x前缀表示。

 

3.寻址

intel语法的变址+基址的时候

[基址寄存器+变址寄存器X比例因子+立即数],eg:[bx+si*4+1],很简单啊。。。

AT&T就比较难懂了

立即数(基址寄存器,变址寄存器,比例因子),eg :$1(%bx,%si,$4)再带上之前说的两个标准,看得确实蛋疼了。。。

 

4.后缀修饰

intel语法使用 word ptr 之类的命令来指明寻址内存时读取数据的长度。虽然vim C-N上下文补全很方便,但是还是蛮蛋疼的。

AT&T直接使用后缀表示,l=long=32bits,w=word=16bits,b=byte=8bits.比起intel语法方便多了

同样,有明确长度时(例如指明了寄存器),就可以省略后缀修饰。

 

其余变化应该不大

 

C函数传递。

这个直接关系到C与汇编的混合编程。

当然,这段写的最好的还是gnu as manual。

这里也主要是几个要点。

1.C函数的参数

C语言是通过堆栈传参的。按照参数表顺序依次将参数压入堆栈,然后call。

 

2.C函数的frame pointer

用gcc编译的时候,如果不用-fomit-frame-pointer选项的话,默认是会开启frame pointer功能。

此时在函数体一开始一般会有

pushl %ebp

mov %esp,%ebp;这两行等价于enter这一条命令

这两句,这就是建立了frame pointer。

此时esp,ebp都

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值