C - 内联汇编,存储数字出错

时间:2015-10-21 17:58:44

标签: c assembly inline-assembly

我对装配很新。实际上,我以前从未接触过它,我有点需要在学校项目中使用它(我真的不需要它,但我觉得它有点必要)。我不能使用变量,所以我需要做的是将一个数字移动到eax(或其他寄存器)的汇编代码,而另一个函数则将输入与寄存器中的值进行比较 - 如果可能的话。我在C中使用asm函数执行此操作,但是汇编部分是需要修复的部分.. AT& T语法,linux,使用gcc -std = gnu99编译,我尝试了一些值:

标志:Curr:结果

1:0:相等,

0:0:相等,

-1:0:相等,

1:1:较小

0:1:较小

-1:1:较小

1:-1:更大

0:-1:更大

1:-1:更大

所以标志一直被覆盖为0,我该如何防止呢?

#include <stdio.h>

void setFlag(), compare(), smaller(), larger(), equal();
int getFlag(), getCurr();

int main()
{
    setFlag();
    compare();
    return 0;
}

void setFlag()
{
    asm("movl %0, %%ebx;"
        :: "r" (getFlag())
        : "%ebx");
}

void compare()
{
    asm("cmpl %0, %%ebx;"
        "je 2f;"
        "jg 1f;"

        "call smaller;"
        "jmp 3f;"

        "1:"
        "call larger;"
        "jmp 3f;"

        "2:"
        "call equal;"

        "3:"
        :: "r" (getCurr()));    
}

void smaller() { printf("smaller\n"); }

void larger() { printf("larger\n"); }

void equal() { printf("equal\n"); }

int getFlag() { return 5; }

int getCurr() { return 3; }

1 个答案:

答案 0 :(得分:0)

以下是比较函数的反汇编:

  00000000004005e0 <compare>:
  4005e0:   b8 03 00 00 00          mov    $0x3,%eax
  4005e5:   39 c0                   cmp    %eax,%eax
  4005e7:   74 10                   je     4005f9 <eq>
  4005e9:   7f 07                   jg     4005f2 <lrg>
  4005eb:   e8 10 00 00 00          callq  400600 <smaller>
  4005f0:   eb 0c                   jmp    4005fe <out>

注意什么?

你正在混淆你的比喻。使用%0等时,不能直接使用%% eax。编译器可能会将%0分配给%eax,因为您没有告诉它您想要使用它。

您需要的是注册特定约束。 %eax的约束是“a”。然后申请。例如,如果您有两个寄存器,一个必须是%eax,请执行=a (p), =r (q)。现在,p变量[using%0]映射到%eax,q变量[using%1]映射到任何可用的寄存器。

HOWEVER 在调用了%eax的inEax之后,它没有机会不立即被覆盖。实际上,在函数返回后,您不能指望任何寄存器具有任何特定的状态/值。

如果将所有汇编代码放在手工制作的.s文件中,可以执行此操作。你可以拥有你想要的任何调用约定(例如%ecx中的返回值)