快速业务通道

__asm__ __volatile__内嵌汇编用法简述

作者 佚名技术 来源 Linux系统 浏览 发布时间 2012-04-14
printf ("write lx to p15/c1n", value);
#endif
__asm__ __volatile__(
"mcr p15, 0, %0, c1, c0, 0 @ write it backn"
:
: "r" (value) @编译器选择一个R*寄存器
: "memory");
read_p15_c1 ();
}

6.、Clobber/Modify

有时候,你想通知GCC当前内联汇编语句可能会对某些寄存器或内存进行修改,希望GCC在编译时能够将这一点考虑进去.那么你就可以在Clobber/Modify域声明这些寄存器或内存.这种情况一般发生在一个寄存器出现在"Instruction List",但却不是由Input/Output操作表达式所指定的,也不是在一些Input/Output操作表达式使用"r"约束时由GCC 为其选择的,同时此寄存器被"Instruction List"中的指令修改,而这个寄存器只是供当前内联汇编临时使用的情况.

例如:

__asm__ ("mov R0, #0x34" : : : "R0");

寄存器R0出现在"Instruction List中",并且被mov指令修改,但却未被任何Input/Output操作表达式指定,你需要在Clobber/Modify域指定"R0",以让GCC知道这一点.

你在Input/Output操作表达式所指定的寄存器,或当你为一些Input/Output操作表达式使用"r"约束,让GCC为你选择一个寄存器时,GCC对这些寄存器是非常清楚的——它知道这些寄存器是被修改的,你根本不需要在Clobber/Modify域再声明它们.但除此之外, GCC对剩下的寄存器中哪些会被当前的内联汇编修改一无所知.如果你真的在当前内联汇编指令中修改了它们,那么就最好在Clobber/Modify 中声明它们,让GCC针对这些寄存器做相应的处理.否则有可能会造成寄存器的不一致,从而造成程序执行错误.

如果一个内联汇编语句的Clobber/Modify域存在"memory",那么GCC会保证在此内联汇编之前,如果某个内存的内容被装入了寄存器,那么在这个内联汇编之后,如果需要使用这个内存处的内容,就会直接到这个内存处重新读取,而不是使用被存放在寄存器中的拷贝.这个 时候寄存器中的拷贝已经很可能和内存处的内容不一致了.

这只是使用"memory"时,GCC会保证做到的一点,但这并不是全部.使用"memory"是向GCC声明内存发生了变化,而内存发生变化带来的影响并不止这一点.

例如:

int main(int __argc, char* __argv[])
{
int* __p = (int*)__argc;
(*__p) = 9999;
__asm__("":::"memory");
if((*__p) == 9999)
return 5;
return (*__p);
}

本例中,如果没有那条内联汇编语句,那个if语句的判断条件就完全是一句废话.GCC在优化时会意识到这一点,而直接只生成return 5的汇编代码,而不会再生成if语句的相关代码,而不会生成return (*__p)的相关代码.但你加上了这条内联汇编语句,它除了声明内存变化之外,什么都没有做.但GCC此时就不能简单的认为它不需要判断都知道 (*__p)一定与9999相等,它只有老老实实生成这条if语句的汇编代码,一起相关的两个return语句相关代码.

另外在linux内核中内存屏障也是基于它实现的include/asm/system.h中

# define barrier() _asm__volatile_("": : :"memory")

主要是保证程序的执行遵循顺序一致性.呵呵,有的时候你写代码的顺序,不一定是最终执行的顺序,这个是处理器有关的.

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号