【问题标题】:How to set a variable in GCC with Intel syntax inline assembly?如何使用英特尔语法内联汇编在 GCC 中设置变量?
【发布时间】:2011-07-20 20:09:21
【问题描述】:

为什么这段代码不将temp 设置为 1?我该怎么做呢?

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

【问题讨论】:

    标签: gcc inline-assembly intel-syntax


    【解决方案1】:

    你希望temp 成为输出,而不是输入,我想。试试:

      __asm__(
          ".intel_syntax;"
          "mov eax, %1;"
          "mov %0, eax;"
          ".att_syntax;"
          : "=r"(temp)
          : "r"(1) 
          : "eax");
    

    【讨论】:

    • 哦,我不敢相信我错过了 x___x 你绝对是对的;这就是问题所在。非常感谢!
    • @Mehrdad - 我认为您也需要其他顺序的说明,现在我看到了。已编辑!
    • @Mehrdad - 只是巧合。您可以查看输出二进制文件以了解确切原因。在我的机器上,它为输入和输出重复使用相同的寄存器,所以它最终看起来像它的工作方式。
    【解决方案2】:

    此代码可以实现您想要实现的目标。希望对您有所帮助:

    #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);
    }
    

    【讨论】:

    【解决方案3】:

    您必须将参数传递给 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”。

    【讨论】:

    • 头文件 conio.h 和 getch() 是非标准的,应该用标准替代品替换。此链接faq.cprogramming.com/cgi-bin/… 显示了如何执行此操作的标准 C 和 C++ 示例。它还提到了 getch() 和其他特定于平台的方法,但最好提供使用标准构造的示例,尤其是当您不知道用户在哪个平台上运行时。
    • 这在语法上是有效的,但是您缺少对 asm 语句的约束,因此编译器不知道您正在使用哪些寄存器,或者 asm 语句修改了全局 myVar。如果您使用优化编译,这可能很容易中断。 这是一个如何使用内联 asm 的示例。它需要是一个单独的 asm 语句,最好带有 "=m"(myvar) 输出。另请参阅gcc.gnu.org/wiki/ConvertBasicAsmToExtended
    猜你喜欢
    • 2012-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-09
    • 2016-07-13
    • 2018-10-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多