如何使用Intel语法的内联汇编在GCC中设置变量?

17

为什么这段代码没有将temp设置为1?我应该怎么做才能实现这个目标?

int temp;
__asm__(
    ".intel_syntax;"
    "mov %0, eax;"
    "mov eax, %1;"
    ".att_syntax;"
    : : "r"(1), "r"(temp) : "eax");
printf("%d\n", temp);
3个回答

17
你希望temp成为输出而不是输入,我想。尝试:
  __asm__(
      ".intel_syntax;"
      "mov eax, %1;"
      "mov %0, eax;"
      ".att_syntax;"
      : "=r"(temp)
      : "r"(1) 
      : "eax");

哦,我简直不敢相信我错过了 x___x 你肯定是对的;那就是问题所在。非常感谢! - user541686
@Mehrdad - 我认为您现在需要交换指令的顺序,现在我看一下。已编辑! - Carl Norum
@Mehrdad - 只是巧合。 你可以查看输出二进制文件,理解原因。在我的机器上,它将输入和输出重用同一个寄存器,所以它看起来像是有效的。 - Carl Norum

8

这段代码可以实现您想要达到的目标。希望对您有帮助:

#include <stdio.h>

int main(void)
{
    /* Compile with C99 */
    int temp=0;

    asm
    (   ".intel_syntax;"
        "mov %0, 1;"
        ".att_syntax;"
        : "=r"(temp)
        :                   /* no input*/
    );
    printf("temp=%d\n", temp);
}

顺便提一下,要使用att_syntax的语句应该是:asm("mov $1, %0;" : "=r"(temp) :/* no input*/); - DrBeco
2
相关:在.intel_syntax GNU C内联汇编中引用内存操作数。如果您使用内存输出操作数,则需要使用-masm=intel进行编译。 - Peter Cordes
谢谢你的推荐,Peter。 - DrBeco

5

您需要向GCC汇编器传递参数。

gcc.exe -masm=intel -c Main.c
gcc.exe Main.o -oMain.exe

你有如下这样的C代码:

#include <conio.h>
#include <stdio.h>

int myVar = 0;

int main(int argc, char *argv[])
{
    asm("mov eax, dword ptr fs:[0x18]");
    asm("mov eax, dword ptr ds:[eax+0x30]");
    asm("movzx eax, byte ptr ds:[eax+0x2]");
    asm("mov _myVar, eax");

    if(myVar == 1) printf("This program has been debugged.\r\n");
    printf("Welcome.\r\n");
    getch();

    return 0;
}

在asm()关键字中的每个变量前都加下划线(_),否则它将无法识别。

而且asm()关键字对于每个十六进制整数使用前缀“ 0x”,而不是后缀“ h”。


1
这是语法上有效的,但您在asm语句中缺少约束条件,因此编译器不知道使用哪些寄存器,或者该asm语句是否修改全局变量myVar。如果进行了优化编译,这可能会很容易地导致错误。** 这是如何使用inline asm的示例。 ** 它需要成为一个单一的asm语句,最好带有一个“= m”(myvar)输出。 参见https://gcc.gnu.org/wiki/ConvertBasicAsmToExtended - Peter Cordes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接