首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >内联程序集没有使用clang生成我希望的结果。

内联程序集没有使用clang生成我希望的结果。
EN

Stack Overflow用户
提问于 2020-07-14 05:01:50
回答 1查看 493关注 0票数 1

我正在使用内嵌组装x86_64与clang。我希望将确切的程序集编译到我在源代码中指定的二进制文件中,但出于某种原因,clang一直在更改它。只有在我使用AT&T GCC样式程序集时才会发生这种情况,而在MSVC __asm中则不会发生这种情况。我想使用AT&T样式程序集,因为我的其他代码经常使用AT&T样式,而且我希望保持一致。以下是我的程序集代码的声明方式:

代码语言:javascript
复制
__attribute__((naked)) void XxInternalOperation()
{
    asm volatile("mov %%rcx, %%rax\n\t"
        "mov %0, %%r11\n\t"
        "jmpq *%%r11"
        :
        : "r" (jumpAddrAbsolute)
        : "r11");
}

我希望我的程序集代码表示这个英特尔代码:

代码语言:javascript
复制
mov rax, rcx
mov r11, jmpAddrAbsolute ; <-- this is an unsigned long long variable
jmp r11

但是,在IDA中,一个快速的分解显示了一些其他的东西:

代码语言:javascript
复制
mov rax, cs:jumpAddrAbsolute
mov rax, rcx
mov r11, rax
jmp r11

有什么方法可以得到我想要的确切的装配代码吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-07-14 09:30:07

Clang不会“改变”您的程序集。它完全按照您的要求执行,即:它选择一个寄存器(这就是r约束的意思),并以%0代替它。注意,这个寄存器也可以是rax,在这种情况下,您的代码将无法工作。如果希望clang选择内存操作数,则使用m约束。有关gcc式内联装配的详细信息,请参阅gcc手册。下面是一个例子:

代码语言:javascript
复制
extern unsigned long long jumpAddrAbsolute;

__attribute__((naked)) void XxInternalOperation()
{
    asm volatile("mov %%rcx, %%rax\n\t"
        "mov %0, %%r11\n\t"
        "jmpq *%%r11"
        :
        : "m" (jumpAddrAbsolute)
        : "r11", "rax");
}

该文件汇编为:

代码语言:javascript
复制
movq    %rcx, %rax
movq    jumpAddrAbsolute(%rip), %r11
jmpq    *%r11

这似乎是你想要的。

请注意,自从您在第一条指令中使用rax后,我已经将它标记为clobbered。请进一步注意,在执行此内联程序集语句时,不能保证rcx保存任何特定的值。编译器可以自由地将其设置为它喜欢的任何值。

还请注意,编译器可能决定内联XxInternalOperation,在这种情况下,间接跳转将产生在调用方中执行尾调用的意外副作用。考虑将函数标记为noinline以避免这种情况。

不过,一般来说,在内联程序集中执行跳转或调用通常是错误方法的标志,通常会导致各种问题。如果您已经决定使用这个内联程序集解决问题的一些细节,我可能会向您建议一个更好的解决方案。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62888372

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档