gcc中的内嵌汇编语言.docVIP

  1. 1、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
gcc中的内嵌汇编语言 作者:欧阳光 ouyangguang@263.net 初次接触到ATT格式的汇编代码,看着那一堆莫名其妙的怪符号,真是有点痛不欲生的感觉, 只好慢慢地去啃gcc文档,在似懂非懂的状态下过了一段时间。后来又在网上找到了灵溪写的 《gcc中的内嵌汇编语言》一文,读后自感大有裨益。几个月下来,接触的源代码多了以后,慢慢 有了一些经验。为了使初次接触ATT格式的汇编代码的同志不至于遭受我这样的痛苦,就整理出 该文来和大家共享.如有错误之处,欢迎大家指正,共同提高. 本文主要以举例的方式对gcc中的内嵌汇编语言进行进一步的解释。 一、gcc对内嵌汇编语言的处理方式 gcc在编译内嵌汇编语言时,采取的步骤如下 1.变量输入: 根据限定符的内容将输入操作数放入合适的寄存器,如果限定符指定为立即 数(I)或内存变量(m),则该步被省略,如果限定符没有具体指定输入操作数的类型(如 常用的g),gcc会视需要决定是否将该操作数输入到某个寄存器.这样每个占位符都与某 个寄存器,内存变量,或立即数形成了一一对应的关系.这就是对第二个冒号后内容的解释. 如::a(foo),I(100),m(bar)表示%0对应eax寄存器,%1对应100,%2对应内存变量 bar. 2.生成代码: 然后根据这种一一对应的关系(还应包括输出操作符),用这些寄存器,内存变 量,或立即数来取代汇编代码中的占位符(则有点像宏操作),注意,则一步骤并不检查由这 种取代操作所生成的汇编代码是否合法,例如,如果有这样一条指令asm(movl %0,%1::m(foo),m(bar));如果你用gcc -c -S选项编译该源文件,那么在生成的汇 编文件中,你将会看到生成了movl foo,bar这样一条指令,这显然是错误的.这个错误在稍 后的编译检查中会被发现. 3.变量输出: 按照输出限定符的指定将寄存器的内容输出到某个内存变量中,如果输出操 作数的限定符指定为内存变量(m),则该步骤被省略.这就是对第一个冒号后内容的解 释,如:asm(mov %0,%1:=m(foo),=a(bar):);编译后为 #APP movl foo,eax #NO_APP movl eax,bar 该语句虽然有点怪怪的,但它很好的体现了gcc的运作方式.           再以arch/i386/kernel/apm.c中的一段代码为例,我们来比较一下它们编译前后的情况 源程序 编译后的汇编代码 __asm__ ( pushl %%edi\n\t pushl %%ebp\n\t lcall %%cs:\n\t setc %%al\n\t addl %1,%2\n\t popl %%ebp\n\t popl %%edi\n\t :=a(ea),=b(eb), =c(ec),=d(ed),=S(es) :a(eax_in),b(ebx_in),c(ecx_in) :memory,cc); movl eax_in,%eax movl ebx_in,%ebx movl ecx_in,%ecx #APP pushl %edi pushl %ebp lcall %cs: setc %al addl eb,ec popl %ebp popl %edi #NO_APP movl %eax,ea movl %ebx,eb movl %ecx,ec movl %edx,ed movl %esi,es 二.对第三个冒号后面内容的解释 第三个冒号后面内容主要针对gcc优化处理,它告诉gcc在本段汇编代码中对寄存器和内存的 使用情况,以免gcc在优化处理时产生错误. 1.它可以是eax,ebx,ecx等寄存器名,表示本段汇编代码对该寄存器进行了显式操作, 如 asm (mov %%eax,%0,:=r(foo)::eax);这样gcc在优化时会避免使用eax作临 时变量,或者避免cache到eax的内存变量通过该段汇编码. 下面的代码均用gcc的-O2级优化,它显示了嵌入汇编中第三个冒号后eax的作用   源程序 编译后的汇编代码 正 常 情 况 下 int main() {int bar=1; bar=fun(); bar++; return bar; } pushl %ebp movl %esp,%ebp call fun incl %eax #显然,bar缺省使用eax寄存器 leave ret 加 了 汇 编 后 int main() {int bar=1; bar=fun(); asm volatile( : : : eax); bar++; return bar; } pushl %ebp movl %esp,%ebp #建立堆栈框架 call fun #fun的返回值放

文档评论(0)

gangshou + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档