我对装配很新。实际上,我以前从未接触过它,我有点需要在学校项目中使用它(我真的不需要它,但我觉得它有点必要)。我不能使用变量,所以我需要做的是将一个数字移动到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; }
答案 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中的返回值)