IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

gcc的内联汇编取全局变量地址

SpongeLiu的blog 2012-09-20 13:50:56 累计浏览 5,036 次
本机暂存

    最近在优化一段代码的过程中,用到了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)
        );

    在我之前优化的代码中这么修改了之后,速度确实提升了一些。

同分类推荐文章

  1. 当编程变得不再有趣 (2026-07-06 19:18:00)
  2. 代码在发臭:一个能"闻"出坏味道的 AI 技能,我拿它扫了最新的开源代码 (2026-07-04 16:08:14)
  3. 我的 Claude Code 常用 SKILLS 和工具 (2026-06-29 08:00:00)

查看更多 开发者 文章 →

建议继续学习

  1. 由浅入深探究mysql索引结构原理、性能分析与优化 (累计阅读 16,617)
  2. 一次神奇的MySQL优化 (累计阅读 6,133)
  3. mysql索引浅析 (累计阅读 5,374)
  4. 趣题:公司应该雇用多少员工? (累计阅读 5,000)
  5. 趣题:八等分一张圆饼最少需要多少刀? (累计阅读 4,010)
  6. 在2048里能够得到的最大的数是多少? (累计阅读 3,830)
  7. MySQL中order by的实现 和 by rand() 和优化 (累计阅读 3,592)
  8. MogileFS 的安装(MogileFS 系列2) (累计阅读 3,458)
  9. 如何在AIX中编译Perl (累计阅读 3,273)
  10. GCC编译错误 (累计阅读 3,059)