更新
将第二行程序集更改为实际使用的助记符(mflr
),并在底部添加了更多信息。
我遇到了一些代码(使用gcc),类似于以下内容(释义):
#define SOME_MACRO( someVar ) \
do { \
__asm__ ( \
" b 0f\n" \
"0: mflr %0\n" \
: "=r"( someVar ) \
); \
} while(0)
...其中b
指令(ppc)是一个简短的jmp而mflr
正在获取'链接寄存器'的内容 - 在某些方面类似于程序计数器。我也已经看过英特尔代码的这种事情(参见this问题中接受的答案)。
该分支充当无操作...我的问题:这有什么用途?
我猜它与分支预测的东西有关,但到目前为止我只是在搜索时使用这个成语找到了人们的代码。
看起来我在分支预测猜测上错了。 mflr
抓取链接寄存器的内容。
所以,我的问题归结为:为什么分支是必要的。
答案 0 :(得分:1)
像这样的有趣代码往往发生在somethingelse
中。这些代码的一些已知目的是:
__asm__("call 0f\n0: pop %0\n" : "=r"(pc))
call
推送到堆栈的事实用于检索它。)
请注意,由于红色区域,在64位模式的叶子函数中使用这是不安全的 - 请参阅Inline assembly that clobbers the red zone。在x86_64上执行此操作的正确方法是asm("lea 0f(%%rip), %0\n0:\n" : "=r"(pc))
NOP
槽,运行时跟踪实用程序可以修改以动态挂钩代码。 Solaris DTrace使用此类技术。这样的无条件分支是否会导致分支预测未命中处罚或其他类型的停顿是非常依赖CPU的。