首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >用于直接使用操作码而不是助记符的内联AT&T asm语法

用于直接使用操作码而不是助记符的内联AT&T asm语法
EN

Stack Overflow用户
提问于 2018-09-06 01:02:15
回答 2查看 523关注 0票数 1

由于不幸的原因,我不能进入,我不得不支持一个古老的汇编程序,它没有我需要的助记符的映射。

我知道硬件支持它,但是我似乎找不到任何关于如何使用操作码而不是助记符的在线文档。

有没有人可以参考一下在内联AT&T语法中如何在GCC上做到这一点。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-09-06 01:35:32

幸运的是,rdrand只有一个参数,那就是寄存器。因此,如果您想让编译器自由选择,您只需要涵盖几种情况。注意,它仍然很难看:)

代码语言:javascript
复制
inline int rdrand()
{
    int result;
    __asm__ __volatile__ (
        ".byte 0x0f, 0xc7\n\t"
        ".ifc %0, %%eax\n\t"
        ".byte 0xf0\n\t"
        ".else\n\t"
        ".ifc %0, %%ebx\n\t"
        ".byte 0xf3\n\t"
        ".else\n\t"
        ".ifc %0, %%ecx\n\t"
        ".byte 0xf1\n\t"
        ".else\n\t"
        ".ifc %0, %%edx\n\t"
        ".byte 0xf2\n\t"
        ".else\n\t"
        ".ifc %0, %%esi\n\t"
        ".byte 0xf6\n\t"
        ".else\n\t"
        ".ifc %0, %%edi\n\t"
        ".byte 0xf7\n\t"
        ".else\n\t"
        ".ifc %0, %%ebp\n\t"
        ".byte 0xf5\n\t"
        ".else\n\t"
        ".error \"uknown register\"\n\t"
        ".endif\n\t"
        ".endif\n\t"
        ".endif\n\t"
        ".endif\n\t"
        ".endif\n\t"
        ".endif\n\t"
        ".endif\n\t"
    : "=R" (result) : : "cc");

    // "=R" excludes r8d..r15d in 64-bit mode
    return result;
}

对于64位操作数大小,您将需要一个REX.W (0x48)前缀,但是the "=R" constraint而不是"=r"将避免需要在REX前缀中设置任何其他位。

请注意,rdrand还使用进位标志,该标志的处理留给读者作为练习。gcc6可以使用标志输出操作数,这比setcc更有效。

票数 2
EN

Stack Overflow用户

发布于 2018-09-06 02:02:47

试试这个:

代码语言:javascript
复制
long result;
char success = 0; /* make sure we don't get surprised by setc only writing 8 bits */

/* "rdrand %%rax ; setc %b1" */
asm volatile (".byte 0x48, 0x0f, 0xc7, 0xf0; setc %b1" : "=a"(result), "=qm"(success) :: "cc");

a约束强制编译器对result使用rax寄存器。这就是它得到的最普遍的东西,而不是令人讨厌的。我建议您添加一个配置测试,以检查汇编程序是否理解rdrand,并使用以下代码:

代码语言:javascript
复制
long result;
char success = 0;

#ifdef HAVE_RDRAND
asm volatile ("rdrand %0; setc %b1" : "=r"(result), "=qm"(success) :: "cc");
#else
asm volatile (".byte 0x48, 0x0f, 0xc7, 0xf0; setc %b1" : "=a"(result), "=qm"(success) :: "cc");
#endif

虽然如果汇编器不理解rax,强制编译器使用rdrand寄存器可能会带来很小的性能损失,但允许使用任何寄存器所需的复杂杂乱操作远远超过了这一点。

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

https://stackoverflow.com/questions/52190220

复制
相关文章

相似问题

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