我对 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/