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

标签 c assembly inline-assembly

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

标志:当前:结果

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

最佳答案

这是比较函数的反汇编:

  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 变量 [使用 %0] 映射到 %eax,q 变量 [使用 %1] 映射到任何可用寄存器。

但是在调用 inEax(填充 %eax)之后,它不可能不被立即覆盖。事实上,您不能期望任何寄存器在函数返回后具有任何特定状态/值。

如果您将所有汇编代码放入手动制作的 .s 文件中,您可以做到这一点。您可以使用任何您想要的调用约定(例如%ecx中的返回值)

关于C - 内联汇编,存储数字出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33266153/

相关文章:

在 gcc 内联汇编中调用函数

C - 为什么在循环中创建的变量具有相同的内存地址?

c - 反转字符串时交换指针值时出现段错误

assembly - x86/x64添加位移寻址

c - 使用 GCC 生成可读程序集?

c - 你如何解读这个集会?

c - 有什么简单的方法可以提高这个自旋锁函数的性能吗?

c - Scanf 未知数的整数

具有两个指针的 C 函数

c - 如何从 IAR EWARM 中的内联汇编器调用另一个模块中的 C 函数?