gcc的内联汇编取全局变量地址
浏览:4077次 出处信息
最近在优化一段代码的过程中,用到了gcc的内联汇编。代码中有用到了许多全局变量,比如:
char mi[10]={...}; |
开始的时候,我对全局变量的取址是这样的:
__asm__ ("movq (%2, %1, 1 ), %0" :"=r"(cookie) :"r"(index),"r"(mi) ); |
在一个函数中使用这段代码,一条指令完成了对mi数组的访问,但同时也存在问题,即mi的地址会占用一个寄存器,mi的地址要在早先的时间内被装载到寄存器中(指令由编译器自动生成),同时,被mi占用的寄存器有些情况下不能被其他手工内联的汇编指令随便写入,编译器还没有那么智能帮你讲寄存器的内容保存好。
综上,使用这种方法会存在两方面问题:
1、使用至少两条指令来读取全局变量
2、正确性要小心呵护。
但是,在gcc的O2选项下访问mi变量的时候,因为全局变量的地址在编译时是可以确定的,所以这样的代码
int tmp = mi[3]; |
反汇编出来是
mov 0x405600(%eax), %ebx; |
其中,eax中存的是index,也就是3,ebx是tmp。0x405600是全局变量mi的地址,在编译时就确定了这个地址,所以直接写在指令中了。
由于没系统的学过内联汇编的语法,所以不知道怎么在C语言中直接嵌入全局变量的地址,尝试了几种方法,用约束"P","I"什么的都不行,google也没查到相关的方法,后来在某开源代码中搜了下“(%%”,发现真有类似的方法,原来gcc的内联函数可以直接饮用c的标示符的,可以用下面的代码实现相同的功能:
__asm__ ("movq mi(%1 ), %0" :"=r"(cookie) :"r"(index) ); |
在我之前优化的代码中这么修改了之后,速度确实提升了一些。
建议继续学习:
- GCC编译错误 (阅读:1914)
- 有关最近GCC编译出现的firstdefine问题 (阅读:1771)
- gcc对Template Template Parameters的兼容性 (阅读:1582)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
扫一扫订阅我的微信号:IT技术博客大学习
<< 前一篇:gdb的基本工作原理是什么?
后一篇:统计最近用过的linux命令 >>
文章信息
- 作者:sponge 来源: SpongeLiu的blog
- 标签: gcc 内联汇编
- 发布时间:2012-09-20 13:50:56
近3天十大热文
- [70] IOS安全–浅谈关于IOS加固的几种方法
- [67] Twitter/微博客的学习摘要
- [65] 如何拿下简短的域名
- [62] android 开发入门
- [61] find命令的一点注意事项
- [59] Go Reflect 性能
- [58] 流程管理与用户研究
- [57] 图书馆的世界纪录
- [56] 读书笔记-壹百度:百度十年千倍的29条法则
- [56] Oracle MTS模式下 进程地址与会话信