当前位置: 首页 > 知识库问答 >
问题:

Gcc内联程序集“'asm'操作数有不可能的约束”是什么意思?

沈良策
2023-03-14

我在函数中有以下代码:

void makeSystemCall(uint32_t num, uint32_t param1, uint32_t param2, uint32_t param3){
    asm volatile (
        "mov %0, %%eax\n\t"//Move num to eax
        "mov %1, %%ebx\n\t"//Move param1 to ebx
        "mov %2, %%ecx\n\t"//Move param2 to ecx
        "mov %3, %%edx\n\t"//Move param3 to edx
        "int $0x80"//Call interrupt. Data in eax, ebx, ecx and edx
        : //No output params
        : "r" (num), "r" (param1), "r" (param2), "r" (param3)//Input params
        : "%eax", "%ebx", "%ecx", "%edx" //This handles register state pushing and popping?
    );
}

现在我不知道为什么这不起作用。Gcc说:“错误:'asm'操作数有不可能的约束”我一直在学习Gcc内联汇编教程,我认为这是将参数从c代码带到内联汇编块的正确方法。

我还使用了为32位x86构建的gcc交叉编译器。

共有1个答案

劳研
2023-03-14

使用“r”约束强制编译器将参数加载到暂存寄存器中,然后再将该暂存寄存器用于mov指令之一。根本没有4个暂存寄存器可用。

请改用“g”约束。这是更有效的,因为编译器将能够直接访问您的mov指令中的参数,使用帧指针偏移到目标寄存器的内存访问,而不是在暂存寄存器中访问,然后将暂存寄存器移动到最终目标。

 类似资料:
  • 尝试使用gcc:https://github.com/wolf9466/cpuminer-multi/blob/master/cryptonight_aesni.c编译此源文件时遇到此错误 “CRYPTONIGT_AESNI.c:162:4:错误:操作数约束不一致”

  • 这里是一个虚拟的*z++=*x++**y++指令。请注意,x、y和z指针寄存器必须指定为输入/输出,因为asm会修改它们。 在第一个示例中,在输入操作数中列出和有什么意义?同一份文件指出: 特别是,如果不将输入操作数指定为输出操作数,就无法指定输入操作数被修改。

  • 我正在尝试同时处理MSVC和GCC编译器,同时更新这个代码库以在GCC上工作。但我不确定GCCs内联ASM是如何工作的。现在我并不擅长将ASM转换为C,否则我就会使用C而不是ASM。 我假设ROR13的工作方式类似于,但代码不会产生相同的输出。 什么是将这个内联ASM翻译成GCC的正确方法,或者这个代码的C翻译是什么?

  • 这段代码是正确的,但不是最优的。MULQ是可交换的,因此如果恰好已经在RAX中,那么将保留在其所在的位置并进行乘法是正确的。但是GCC不知道这一点,所以它会发出额外的指令将操作数移到它们预定义的位置。我想告诉GCC,它可以将任何一个输入放在任何一个位置,只要一个输入最终在RAX中,并且MULQ引用了另一个位置。GCC对此有一个语法,称为“多重替代约束”。请注意逗号(但是整个asm()是断开的;请参

  • 谢谢你的帮助。

  • 有没有人要对我说或评论? 跟随生成的程序集 多亏了弄臣的解决之道: